feat(auth): add keeping stats on payments

This commit is contained in:
Karol Sójko
2022-09-05 16:55:37 +02:00
parent 87a5854357
commit 0c176b70f8
13 changed files with 45 additions and 13 deletions

View File

@@ -23,7 +23,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
"test": "jest spec --coverage"
},
"devDependencies": {
"@types/ioredis": "^4.28.10",

View File

@@ -9,7 +9,13 @@ import {
} from '@standardnotes/domain-events'
import { TimerInterface, Timer } from '@standardnotes/time'
import { UAParser } from 'ua-parser-js'
import { AnalyticsStoreInterface, PeriodKeyGenerator, RedisAnalyticsStore } from '@standardnotes/analytics'
import {
AnalyticsStoreInterface,
PeriodKeyGenerator,
RedisAnalyticsStore,
RedisStatisticsStore,
StatisticsStoreInterface,
} from '@standardnotes/analytics'
import { Env } from './Env'
import TYPES from './Types'
@@ -542,9 +548,13 @@ export class ContainerConfigLoader {
.bind<SelectorInterface<boolean>>(TYPES.BooleanSelector)
.toConstantValue(new DeterministicSelector<boolean>())
container.bind<UserSubscriptionServiceInterface>(TYPES.UserSubscriptionService).to(UserSubscriptionService)
const periodKeyGenerator = new PeriodKeyGenerator()
container
.bind<AnalyticsStoreInterface>(TYPES.AnalyticsStore)
.toConstantValue(new RedisAnalyticsStore(new PeriodKeyGenerator(), container.get(TYPES.Redis)))
.toConstantValue(new RedisAnalyticsStore(periodKeyGenerator, container.get(TYPES.Redis)))
container
.bind<StatisticsStoreInterface>(TYPES.StatisticsStore)
.toConstantValue(new RedisStatisticsStore(periodKeyGenerator, container.get(TYPES.Redis)))
if (env.get('SNS_TOPIC_ARN', true)) {
container

View File

@@ -186,6 +186,7 @@ const TYPES = {
BooleanSelector: Symbol.for('BooleanSelector'),
UserSubscriptionService: Symbol.for('UserSubscriptionService'),
AnalyticsStore: Symbol.for('AnalyticsStore'),
StatisticsStore: Symbol.for('AnalyticsStore'),
}
export default TYPES

View File

@@ -1,7 +1,7 @@
import 'reflect-metadata'
import { PaymentSuccessEvent } from '@standardnotes/domain-events'
import { AnalyticsStoreInterface } from '@standardnotes/analytics'
import { AnalyticsStoreInterface, StatisticsStoreInterface } from '@standardnotes/analytics'
import { PaymentSuccessEventHandler } from './PaymentSuccessEventHandler'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@@ -14,8 +14,10 @@ describe('PaymentSuccessEventHandler', () => {
let user: User
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
const createHandler = () => new PaymentSuccessEventHandler(userRepository, getUserAnalyticsId, analyticsStore)
const createHandler = () =>
new PaymentSuccessEventHandler(userRepository, getUserAnalyticsId, analyticsStore, statisticsStore)
beforeEach(() => {
user = {} as jest.Mocked<User>
@@ -29,9 +31,13 @@ describe('PaymentSuccessEventHandler', () => {
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.incrementMeasure = jest.fn()
event = {} as jest.Mocked<PaymentSuccessEvent>
event.payload = {
userEmail: 'test@test.com',
amount: 12.45,
}
})
@@ -39,6 +45,7 @@ describe('PaymentSuccessEventHandler', () => {
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(statisticsStore.incrementMeasure).toHaveBeenCalled()
})
it('should not mark payment failed for analytics if user is not found', async () => {

View File

@@ -1,4 +1,10 @@
import { AnalyticsActivity, AnalyticsStoreInterface, Period } from '@standardnotes/analytics'
import {
AnalyticsActivity,
AnalyticsStoreInterface,
Period,
StatisticsMeasure,
StatisticsStoreInterface,
} from '@standardnotes/analytics'
import { DomainEventHandlerInterface, PaymentSuccessEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
@@ -12,6 +18,7 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
) {}
async handle(event: PaymentSuccessEvent): Promise<void> {
@@ -26,5 +33,11 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
Period.ThisWeek,
Period.ThisMonth,
])
await this.statisticsStore.incrementMeasure(StatisticsMeasure.PaymentSuccess, event.payload.amount, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
}
}

View File

@@ -59,6 +59,7 @@ describe('SubscriptionCancelledEventHandler', () => {
subscriptionName: SubscriptionName.ProPlan,
timestamp,
offline: false,
replaced: false,
}
})

View File

@@ -23,7 +23,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
"test": "jest spec --coverage"
},
"devDependencies": {
"@types/jest": "^28.1.4",

View File

@@ -21,7 +21,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
"test": "jest spec --coverage"
},
"dependencies": {
"@standardnotes/domain-events": "workspace:*",

View File

@@ -21,7 +21,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage --passWithNoTests"
"test": "jest spec --coverage --passWithNoTests"
},
"dependencies": {
"@standardnotes/common": "workspace:*",

View File

@@ -23,7 +23,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage --passWithNoTests"
"test": "jest spec --coverage --passWithNoTests"
},
"devDependencies": {
"@types/jest": "^28.1.4",

View File

@@ -23,7 +23,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
"test": "jest spec --coverage"
},
"dependencies": {
"@standardnotes/common": "workspace:*",

View File

@@ -21,7 +21,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec"
"test": "jest spec"
},
"dependencies": {
"@standardnotes/sncrypto-common": "^1.9.0",

View File

@@ -21,7 +21,7 @@
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
"test": "jest spec --coverage"
},
"dependencies": {
"dayjs": "^1.10.8",