浏览代码

fix(auth): change remaining subscription time stats to percentage

Karol Sójko 2 年之前
父节点
当前提交
5eb957c82a

+ 1 - 1
packages/analytics/src/Domain/Statistics/StatisticsMeasure.ts

@@ -3,7 +3,7 @@ export enum StatisticsMeasure {
   SubscriptionLength = 'subscription-length',
   SubscriptionLength = 'subscription-length',
   RegistrationLength = 'registration-length',
   RegistrationLength = 'registration-length',
   RegistrationToSubscriptionTime = 'registration-to-subscription-time',
   RegistrationToSubscriptionTime = 'registration-to-subscription-time',
-  SubscriptionCancelToExpireTime = 'subscription-cancel-to-expire-time',
+  RemainingSubscriptionTimePercentage = 'remaining-subscription-time-percentage',
   Refunds = 'refunds',
   Refunds = 'refunds',
   NotesCountFreeUsers = 'notes-count-free-users',
   NotesCountFreeUsers = 'notes-count-free-users',
   NotesCountPaidUsers = 'notes-count-paid-users',
   NotesCountPaidUsers = 'notes-count-paid-users',

+ 1 - 1
packages/api-gateway/bin/report.ts

@@ -94,7 +94,7 @@ const requestReport = async (
     StatisticsMeasure.RegistrationLength,
     StatisticsMeasure.RegistrationLength,
     StatisticsMeasure.SubscriptionLength,
     StatisticsMeasure.SubscriptionLength,
     StatisticsMeasure.RegistrationToSubscriptionTime,
     StatisticsMeasure.RegistrationToSubscriptionTime,
-    StatisticsMeasure.SubscriptionCancelToExpireTime,
+    StatisticsMeasure.RemainingSubscriptionTimePercentage,
     StatisticsMeasure.NotesCountFreeUsers,
     StatisticsMeasure.NotesCountFreeUsers,
     StatisticsMeasure.NotesCountPaidUsers,
     StatisticsMeasure.NotesCountPaidUsers,
     StatisticsMeasure.FilesCount,
     StatisticsMeasure.FilesCount,

+ 13 - 0
packages/auth/migrations/1663321030000-add_renewed_at_column.ts

@@ -0,0 +1,13 @@
+import { MigrationInterface, QueryRunner } from 'typeorm'
+
+export class addRenewedAtColumn1663321030000 implements MigrationInterface {
+  name = 'addRenewedAtColumn1663321030000'
+
+  public async up(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query('ALTER TABLE `user_subscriptions` ADD `renewed_at` bigint NULL')
+  }
+
+  public async down(): Promise<void> {
+    return
+  }
+}

+ 15 - 10
packages/auth/src/Domain/Handler/SubscriptionCancelledEventHandler.ts

@@ -27,14 +27,6 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
     @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
     @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
   ) {}
   ) {}
   async handle(event: SubscriptionCancelledEvent): Promise<void> {
   async handle(event: SubscriptionCancelledEvent): Promise<void> {
-    if (event.payload.offline) {
-      await this.updateOfflineSubscriptionCancelled(event.payload.subscriptionId, event.payload.timestamp)
-
-      return
-    }
-
-    await this.updateSubscriptionCancelled(event.payload.subscriptionId, event.payload.timestamp)
-
     const user = await this.userRepository.findOneByEmail(event.payload.userEmail)
     const user = await this.userRepository.findOneByEmail(event.payload.userEmail)
     if (user !== null) {
     if (user !== null) {
       const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: user.uuid })
       const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: user.uuid })
@@ -54,14 +46,27 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
           Period.ThisMonth,
           Period.ThisMonth,
         ])
         ])
 
 
+        const lastPurchaseTime = lastSubscription.renewedAt ?? lastSubscription.updatedAt
         const remainingSubscriptionTime = lastSubscription.endsAt - event.payload.timestamp
         const remainingSubscriptionTime = lastSubscription.endsAt - event.payload.timestamp
+        const totalSubscriptionTime = lastSubscription.endsAt - lastPurchaseTime
+
+        const remainingSubscriptionPercentage = Math.floor((remainingSubscriptionTime / totalSubscriptionTime) * 100)
+
         await this.statisticsStore.incrementMeasure(
         await this.statisticsStore.incrementMeasure(
-          StatisticsMeasure.SubscriptionCancelToExpireTime,
-          remainingSubscriptionTime,
+          StatisticsMeasure.RemainingSubscriptionTimePercentage,
+          remainingSubscriptionPercentage,
           [Period.Today, Period.ThisWeek, Period.ThisMonth],
           [Period.Today, Period.ThisWeek, Period.ThisMonth],
         )
         )
       }
       }
     }
     }
+
+    if (event.payload.offline) {
+      await this.updateOfflineSubscriptionCancelled(event.payload.subscriptionId, event.payload.timestamp)
+
+      return
+    }
+
+    await this.updateSubscriptionCancelled(event.payload.subscriptionId, event.payload.timestamp)
   }
   }
 
 
   private async updateSubscriptionCancelled(subscriptionId: number, timestamp: number): Promise<void> {
   private async updateSubscriptionCancelled(subscriptionId: number, timestamp: number): Promise<void> {

+ 7 - 0
packages/auth/src/Domain/Subscription/UserSubscription.ts

@@ -34,6 +34,13 @@ export class UserSubscription {
   @Index('updated_at')
   @Index('updated_at')
   declare updatedAt: number
   declare updatedAt: number
 
 
+  @Column({
+    name: 'renewed_at',
+    type: 'bigint',
+    nullable: true,
+  })
+  declare renewedAt: number | null
+
   @Column({
   @Column({
     type: 'tinyint',
     type: 'tinyint',
     width: 1,
     width: 1,

+ 2 - 1
packages/auth/src/Infra/MySQL/MySQLUserSubscriptionRepository.spec.ts

@@ -138,7 +138,8 @@ describe('MySQLUserSubscriptionRepository', () => {
 
 
     expect(updateQueryBuilder.update).toHaveBeenCalled()
     expect(updateQueryBuilder.update).toHaveBeenCalled()
     expect(updateQueryBuilder.set).toHaveBeenCalledWith({
     expect(updateQueryBuilder.set).toHaveBeenCalledWith({
-      updatedAt: expect.any(Number),
+      updatedAt: 1000,
+      renewedAt: 1000,
       endsAt: 1000,
       endsAt: 1000,
     })
     })
     expect(updateQueryBuilder.where).toHaveBeenCalledWith('subscription_id = :subscriptionId', {
     expect(updateQueryBuilder.where).toHaveBeenCalledWith('subscription_id = :subscriptionId', {

+ 3 - 2
packages/auth/src/Infra/MySQL/MySQLUserSubscriptionRepository.ts

@@ -88,13 +88,14 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
     return null
     return null
   }
   }
 
 
-  async updateEndsAt(subscriptionId: number, endsAt: number, updatedAt: number): Promise<void> {
+  async updateEndsAt(subscriptionId: number, endsAt: number, timestamp: number): Promise<void> {
     await this.ormRepository
     await this.ormRepository
       .createQueryBuilder()
       .createQueryBuilder()
       .update()
       .update()
       .set({
       .set({
         endsAt,
         endsAt,
-        updatedAt,
+        updatedAt: timestamp,
+        renewedAt: timestamp,
       })
       })
       .where('subscription_id = :subscriptionId', {
       .where('subscription_id = :subscriptionId', {
         subscriptionId,
         subscriptionId,