@aepstore-dev/contracts 1.32.0 → 1.33.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/payments.ts CHANGED
@@ -313,6 +313,122 @@ export interface SalesAnalyticsResponse {
313
313
  refundRate: string;
314
314
  }
315
315
 
316
+ /**
317
+ * ---------------------------------------------------------------------------
318
+ * Premium
319
+ * ---------------------------------------------------------------------------
320
+ */
321
+ export interface GetPremiumPlansRequest {
322
+ }
323
+
324
+ /**
325
+ * One plan per (period). Prices are computed server-side from BASE_PRICE × months
326
+ * × (1 − discount); kept here as canonical strings so the gateway has no math.
327
+ */
328
+ export interface PremiumPlan {
329
+ /** MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12 */
330
+ period: string;
331
+ months: number;
332
+ /** total to charge, Decimal-as-string */
333
+ price: string;
334
+ /** for UI "≈ X ₽/month" */
335
+ monthlyPrice: string;
336
+ discountPercent: string;
337
+ currency: string;
338
+ }
339
+
340
+ export interface PremiumPlansResponse {
341
+ plans: PremiumPlan[];
342
+ baseMonthlyPrice: string;
343
+ }
344
+
345
+ export interface PurchasePremiumRequest {
346
+ userId: string;
347
+ /** MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12 */
348
+ period: string;
349
+ /** BALANCE | YOOKASSA */
350
+ paymentMethod: string;
351
+ /** YooKassa only */
352
+ returnUrl: string;
353
+ /**
354
+ * Save the YooKassa payment_method for future auto-renewals. Ignored for
355
+ * BALANCE. Default true — the UI surfaces a checkbox.
356
+ */
357
+ savePaymentMethod: boolean;
358
+ }
359
+
360
+ export interface PurchasePremiumResponse {
361
+ /** PremiumPayment.id */
362
+ paymentId: string;
363
+ /** empty for BALANCE (instant) or YooKassa-issued */
364
+ confirmationUrl: string;
365
+ /** PENDING (redirect) | COMPLETED (balance) */
366
+ status: string;
367
+ }
368
+
369
+ export interface RunPremiumRenewalsRequest {
370
+ /** safety cap; default 100 */
371
+ maxBatch: number;
372
+ }
373
+
374
+ export interface RunPremiumRenewalsResponse {
375
+ attempted: number;
376
+ succeeded: number;
377
+ failed: number;
378
+ }
379
+
380
+ export interface PremiumPaymentRow {
381
+ id: string;
382
+ userId: string;
383
+ amount: string;
384
+ /** MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12 */
385
+ period: string;
386
+ /** BALANCE | YOOKASSA */
387
+ method: string;
388
+ /** PENDING | COMPLETED | FAILED | REFUNDED */
389
+ status: string;
390
+ isRenewal: boolean;
391
+ createdAt: string;
392
+ completedAt: string;
393
+ refundedAt: string;
394
+ refundedAmount: string;
395
+ /**
396
+ * Convenience: true if this payment is currently inside the 7-day refund
397
+ * window AND status == COMPLETED AND not already refunded.
398
+ */
399
+ refundable: boolean;
400
+ }
401
+
402
+ export interface RefundPremiumRequest {
403
+ userId: string;
404
+ paymentId: string;
405
+ /** optional */
406
+ reason: string;
407
+ }
408
+
409
+ export interface RefundPremiumResponse {
410
+ payment:
411
+ | PremiumPaymentRow
412
+ | undefined;
413
+ /** ISO 8601 after rollback */
414
+ newExpiresAt: string;
415
+ /** true when rollback put expiresAt <= now */
416
+ subscriptionRevoked: boolean;
417
+ }
418
+
419
+ export interface GetMyPremiumPaymentsRequest {
420
+ userId: string;
421
+ page: number;
422
+ limit: number;
423
+ }
424
+
425
+ export interface PremiumPaymentsListResponse {
426
+ items: PremiumPaymentRow[];
427
+ total: number;
428
+ page: number;
429
+ limit: number;
430
+ }
431
+
316
432
  export const PAYMENTS_V1_PACKAGE_NAME = "payments.v1";
317
433
 
318
434
  /**
@@ -352,6 +468,28 @@ export interface PaymentsServiceClient {
352
468
 
353
469
  handlePaymentEvent(request: PaymentEventRequest): Observable<Ok>;
354
470
 
471
+ /** ----- premium ----- */
472
+
473
+ getPremiumPlans(request: GetPremiumPlansRequest): Observable<PremiumPlansResponse>;
474
+
475
+ purchasePremium(request: PurchasePremiumRequest): Observable<PurchasePremiumResponse>;
476
+
477
+ /**
478
+ * 7-day refund window from completedAt. Reverses ledger, calls YooKassa for
479
+ * card purchases, rolls back the subscription's expiresAt by the period.
480
+ */
481
+
482
+ refundPremium(request: RefundPremiumRequest): Observable<RefundPremiumResponse>;
483
+
484
+ getMyPremiumPayments(request: GetMyPremiumPaymentsRequest): Observable<PremiumPaymentsListResponse>;
485
+
486
+ /**
487
+ * Internal — InternalServiceGuard. tasks-service cron triggers due renewals;
488
+ * payments-service iterates ACTIVE subscriptions with autoRenew+savedCard.
489
+ */
490
+
491
+ runPremiumRenewals(request: RunPremiumRenewalsRequest): Observable<RunPremiumRenewalsResponse>;
492
+
355
493
  /** ----- admin ----- */
356
494
 
357
495
  getAdminOverview(request: AdminOverviewRequest): Observable<AdminOverviewResponse>;
@@ -410,6 +548,38 @@ export interface PaymentsServiceController {
410
548
 
411
549
  handlePaymentEvent(request: PaymentEventRequest): Promise<Ok> | Observable<Ok> | Ok;
412
550
 
551
+ /** ----- premium ----- */
552
+
553
+ getPremiumPlans(
554
+ request: GetPremiumPlansRequest,
555
+ ): Promise<PremiumPlansResponse> | Observable<PremiumPlansResponse> | PremiumPlansResponse;
556
+
557
+ purchasePremium(
558
+ request: PurchasePremiumRequest,
559
+ ): Promise<PurchasePremiumResponse> | Observable<PurchasePremiumResponse> | PurchasePremiumResponse;
560
+
561
+ /**
562
+ * 7-day refund window from completedAt. Reverses ledger, calls YooKassa for
563
+ * card purchases, rolls back the subscription's expiresAt by the period.
564
+ */
565
+
566
+ refundPremium(
567
+ request: RefundPremiumRequest,
568
+ ): Promise<RefundPremiumResponse> | Observable<RefundPremiumResponse> | RefundPremiumResponse;
569
+
570
+ getMyPremiumPayments(
571
+ request: GetMyPremiumPaymentsRequest,
572
+ ): Promise<PremiumPaymentsListResponse> | Observable<PremiumPaymentsListResponse> | PremiumPaymentsListResponse;
573
+
574
+ /**
575
+ * Internal — InternalServiceGuard. tasks-service cron triggers due renewals;
576
+ * payments-service iterates ACTIVE subscriptions with autoRenew+savedCard.
577
+ */
578
+
579
+ runPremiumRenewals(
580
+ request: RunPremiumRenewalsRequest,
581
+ ): Promise<RunPremiumRenewalsResponse> | Observable<RunPremiumRenewalsResponse> | RunPremiumRenewalsResponse;
582
+
413
583
  /** ----- admin ----- */
414
584
 
415
585
  getAdminOverview(
@@ -445,6 +615,11 @@ export function PaymentsServiceControllerMethods() {
445
615
  "listWithdrawals",
446
616
  "processWithdrawal",
447
617
  "handlePaymentEvent",
618
+ "getPremiumPlans",
619
+ "purchasePremium",
620
+ "refundPremium",
621
+ "getMyPremiumPayments",
622
+ "runPremiumRenewals",
448
623
  "getAdminOverview",
449
624
  "adminListTransactions",
450
625
  "getUserFinance",
package/gen/users.ts CHANGED
@@ -19,6 +19,16 @@ export enum UserFieldsType {
19
19
  UNRECOGNIZED = -1,
20
20
  }
21
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
+
22
32
  export interface User {
23
33
  id: string;
24
34
  email: string;
@@ -160,6 +170,18 @@ export interface PublicProfileResponse {
160
170
  isOwner: boolean;
161
171
  /** viewer is subscribed to this profile (false when anonymous / self) */
162
172
  isSubscribed: boolean;
173
+ /**
174
+ * Premium fields — populated only when the profile owner has an active
175
+ * PremiumSubscription. Non-premium viewers and non-premium profiles see
176
+ * empty strings / false.
177
+ */
178
+ isPremium: boolean;
179
+ profileColor: string;
180
+ avatarBorder: AvatarBorder | undefined;
181
+ animatedAvatarUrl: string;
182
+ animatedBannerUrl: string;
183
+ /** ISO 8601, empty when not premium */
184
+ premiumExpiresAt: string;
163
185
  }
164
186
 
165
187
  export interface UpdateProfileRequest {
@@ -173,6 +195,14 @@ export interface UpdateProfileRequest {
173
195
  countryId: string;
174
196
  timezone: string;
175
197
  socialMedia: CreateSocialMedia[];
198
+ /**
199
+ * Premium-only fields — rejected with FAILED_PRECONDITION when the caller
200
+ * has no active premium. Empty string clears the value.
201
+ */
202
+ profileColor: string;
203
+ avatarBorderId: string;
204
+ animatedAvatarUrl: string;
205
+ animatedBannerUrl: string;
176
206
  }
177
207
 
178
208
  export interface UpdateUserRequest {
@@ -260,6 +290,94 @@ export interface SubscriptionResponse {
260
290
  subscribersCount: number;
261
291
  }
262
292
 
293
+ export interface GetMyPremiumRequest {
294
+ userId: string;
295
+ }
296
+
297
+ export interface PremiumStateResponse {
298
+ isActive: boolean;
299
+ /** ACTIVE | EXPIRED | CANCELED | empty (never purchased) */
300
+ status: string;
301
+ currentPeriod: PremiumPeriod;
302
+ /** ISO 8601, empty when never purchased */
303
+ startedAt: string;
304
+ /** ISO 8601 */
305
+ expiresAt: string;
306
+ autoRenew: boolean;
307
+ hasSavedPaymentMethod: boolean;
308
+ }
309
+
310
+ export interface SetPremiumAutoRenewRequest {
311
+ userId: string;
312
+ enabled: boolean;
313
+ }
314
+
315
+ /**
316
+ * Internal — payments-service hands us the period that was just paid for, plus
317
+ * the YooKassa payment_method id (empty for balance/non-recurring purchases).
318
+ */
319
+ export interface ActivatePremiumRequest {
320
+ userId: string;
321
+ period: PremiumPeriod;
322
+ /** empty for BALANCE / one-shot */
323
+ paymentMethodId: string;
324
+ /** false = first purchase; true = cron-driven renewal */
325
+ isRenewal: boolean;
326
+ }
327
+
328
+ export interface IsPremiumActiveRequest {
329
+ userId: string;
330
+ }
331
+
332
+ export interface IsPremiumActiveResponse {
333
+ isActive: boolean;
334
+ }
335
+
336
+ export interface AvatarBorder {
337
+ id: string;
338
+ code: string;
339
+ name: string;
340
+ description: string;
341
+ imageUrl: string;
342
+ isAnimated: boolean;
343
+ source: string;
344
+ sortOrder: number;
345
+ isActive: boolean;
346
+ }
347
+
348
+ export interface ListAvatarBordersRequest {
349
+ /** admin-only — gateway gates by role */
350
+ includeInactive: boolean;
351
+ /** optional filter */
352
+ source: string;
353
+ }
354
+
355
+ export interface ListAvatarBordersResponse {
356
+ items: AvatarBorder[];
357
+ }
358
+
359
+ export interface UpsertAvatarBorderRequest {
360
+ /** empty = create */
361
+ id: string;
362
+ /** required when creating */
363
+ code: string;
364
+ name: string;
365
+ description: string;
366
+ imageUrl: string;
367
+ isAnimated: boolean;
368
+ source: string;
369
+ sortOrder: number;
370
+ isActive: boolean;
371
+ }
372
+
373
+ export interface DeleteAvatarBorderRequest {
374
+ id: string;
375
+ }
376
+
377
+ export interface DeleteAvatarBorderResponse {
378
+ ok: boolean;
379
+ }
380
+
263
381
  export const USERS_V1_PACKAGE_NAME = "users.v1";
264
382
 
265
383
  export interface UsersServiceClient {
@@ -286,6 +404,37 @@ export interface UsersServiceClient {
286
404
  banUser(request: BanUserRequest): Observable<UserResponse>;
287
405
 
288
406
  unbanUser(request: UnbanUserRequest): Observable<UserResponse>;
407
+
408
+ /**
409
+ * Premium (paid). State lives in users-service; payments-service handles
410
+ * money and calls ActivatePremium (internal) on completion.
411
+ */
412
+
413
+ getMyPremium(request: GetMyPremiumRequest): Observable<PremiumStateResponse>;
414
+
415
+ setPremiumAutoRenew(request: SetPremiumAutoRenewRequest): Observable<PremiumStateResponse>;
416
+
417
+ /**
418
+ * Internal — InternalServiceGuard. Called by payments-service after a
419
+ * successful premium payment (balance or YooKassa webhook).
420
+ */
421
+
422
+ activatePremium(request: ActivatePremiumRequest): Observable<PremiumStateResponse>;
423
+
424
+ /** Internal — fast lookup for the commission engine in payments-service. */
425
+
426
+ isPremiumActive(request: IsPremiumActiveRequest): Observable<IsPremiumActiveResponse>;
427
+
428
+ /**
429
+ * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
430
+ * are admin only (gateway enforces with RolesGuard).
431
+ */
432
+
433
+ listAvatarBorders(request: ListAvatarBordersRequest): Observable<ListAvatarBordersResponse>;
434
+
435
+ upsertAvatarBorder(request: UpsertAvatarBorderRequest): Observable<AvatarBorder>;
436
+
437
+ deleteAvatarBorder(request: DeleteAvatarBorderRequest): Observable<DeleteAvatarBorderResponse>;
289
438
  }
290
439
 
291
440
  export interface UsersServiceController {
@@ -326,6 +475,51 @@ export interface UsersServiceController {
326
475
  banUser(request: BanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
327
476
 
328
477
  unbanUser(request: UnbanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
478
+
479
+ /**
480
+ * Premium (paid). State lives in users-service; payments-service handles
481
+ * money and calls ActivatePremium (internal) on completion.
482
+ */
483
+
484
+ getMyPremium(
485
+ request: GetMyPremiumRequest,
486
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
487
+
488
+ setPremiumAutoRenew(
489
+ request: SetPremiumAutoRenewRequest,
490
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
491
+
492
+ /**
493
+ * Internal — InternalServiceGuard. Called by payments-service after a
494
+ * successful premium payment (balance or YooKassa webhook).
495
+ */
496
+
497
+ activatePremium(
498
+ request: ActivatePremiumRequest,
499
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
500
+
501
+ /** Internal — fast lookup for the commission engine in payments-service. */
502
+
503
+ isPremiumActive(
504
+ request: IsPremiumActiveRequest,
505
+ ): Promise<IsPremiumActiveResponse> | Observable<IsPremiumActiveResponse> | IsPremiumActiveResponse;
506
+
507
+ /**
508
+ * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
509
+ * are admin only (gateway enforces with RolesGuard).
510
+ */
511
+
512
+ listAvatarBorders(
513
+ request: ListAvatarBordersRequest,
514
+ ): Promise<ListAvatarBordersResponse> | Observable<ListAvatarBordersResponse> | ListAvatarBordersResponse;
515
+
516
+ upsertAvatarBorder(
517
+ request: UpsertAvatarBorderRequest,
518
+ ): Promise<AvatarBorder> | Observable<AvatarBorder> | AvatarBorder;
519
+
520
+ deleteAvatarBorder(
521
+ request: DeleteAvatarBorderRequest,
522
+ ): Promise<DeleteAvatarBorderResponse> | Observable<DeleteAvatarBorderResponse> | DeleteAvatarBorderResponse;
329
523
  }
330
524
 
331
525
  export function UsersServiceControllerMethods() {
@@ -343,6 +537,13 @@ export function UsersServiceControllerMethods() {
343
537
  "deleteSubscription",
344
538
  "banUser",
345
539
  "unbanUser",
540
+ "getMyPremium",
541
+ "setPremiumAutoRenew",
542
+ "activatePremium",
543
+ "isPremiumActive",
544
+ "listAvatarBorders",
545
+ "upsertAvatarBorder",
546
+ "deleteAvatarBorder",
346
547
  ];
347
548
  for (const method of grpcMethods) {
348
549
  const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aepstore-dev/contracts",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "Protobuf definitions for aepstore microservices",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",