mirror of
https://github.com/standardnotes/server
synced 2026-01-17 05:04:27 -05:00
Compare commits
10 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7cbc8966e | ||
|
|
89502bed63 | ||
|
|
4952b48db6 | ||
|
|
52a257abb1 | ||
|
|
7480fb089b | ||
|
|
0f65c051ab | ||
|
|
7b62c7a967 | ||
|
|
5c3db2cb29 | ||
|
|
7008cbd363 | ||
|
|
cdb7fcf831 |
@@ -3,6 +3,36 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.7.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.7.0...@standardnotes/analytics@2.7.1) (2022-11-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add missing created at column ([89502be](https://github.com/standardnotes/server/commit/89502bed638b17301e42e0d5916635b0a59f585d))
|
||||
|
||||
# [2.7.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.6.0...@standardnotes/analytics@2.7.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription canceled ([52a257a](https://github.com/standardnotes/server/commit/52a257abb16034134a50474fbbb2493a00c58b99))
|
||||
|
||||
# [2.6.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.5.0...@standardnotes/analytics@2.6.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription refunded ([0f65c05](https://github.com/standardnotes/server/commit/0f65c051abcff805e920f91d338e5fadda7905a9))
|
||||
|
||||
# [2.5.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.4.0...@standardnotes/analytics@2.5.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription expired ([5c3db2c](https://github.com/standardnotes/server/commit/5c3db2cb29a929e44b63eb8226ce4ad1d14f8a99))
|
||||
|
||||
# [2.4.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.3.1...@standardnotes/analytics@2.4.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription renewed ([cdb7fcf](https://github.com/standardnotes/server/commit/cdb7fcf8311fecfabe3ef9eb656cd6ec57b87de0))
|
||||
|
||||
## [2.3.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.3.0...@standardnotes/analytics@2.3.1) (2022-11-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class addMissingCreatedAt1667994036734 implements MigrationInterface {
|
||||
name = 'addMissingCreatedAt1667994036734'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `created_at` bigint NOT NULL')
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `created_at`')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.3.1",
|
||||
"version": "2.7.1",
|
||||
"engines": {
|
||||
"node": ">=14.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -9,14 +9,19 @@ import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { Result } from '../Core/Result'
|
||||
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
|
||||
describe('SubscriptionCancelledEventHandler', () => {
|
||||
let event: SubscriptionCancelledEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let saveRevenueModification: SaveRevenueModification
|
||||
|
||||
const createHandler = () => new SubscriptionCancelledEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore)
|
||||
const createHandler = () =>
|
||||
new SubscriptionCancelledEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, saveRevenueModification)
|
||||
|
||||
beforeEach(() => {
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
@@ -30,6 +35,7 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||
|
||||
event = {} as jest.Mocked<SubscriptionCancelledEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.type = 'SUBSCRIPTION_CANCELLED'
|
||||
event.payload = {
|
||||
subscriptionId: 1,
|
||||
userEmail: 'test@test.com',
|
||||
@@ -41,7 +47,13 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||
timestamp: 1,
|
||||
offline: false,
|
||||
replaced: false,
|
||||
userExistingSubscriptionsCount: 1,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||
})
|
||||
|
||||
it('should track subscription cancelled statistics', async () => {
|
||||
@@ -55,6 +67,7 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
|
||||
@@ -65,5 +78,6 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,10 +4,14 @@ import { inject, injectable } from 'inversify'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Email } from '../Common/Email'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
|
||||
@injectable()
|
||||
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
|
||||
@@ -15,10 +19,11 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||
) {}
|
||||
|
||||
async handle(event: SubscriptionCancelledEvent): Promise<void> {
|
||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
@@ -26,6 +31,17 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
])
|
||||
|
||||
await this.trackSubscriptionStatistics(event)
|
||||
|
||||
await this.saveRevenueModification.execute({
|
||||
billingFrequency: event.payload.billingFrequency,
|
||||
eventType: SubscriptionEventType.create(event.type).getValue(),
|
||||
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
|
||||
payedAmount: event.payload.payAmount,
|
||||
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||
subscriptionId: event.payload.subscriptionId,
|
||||
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||
userUuid,
|
||||
})
|
||||
}
|
||||
|
||||
private async trackSubscriptionStatistics(event: SubscriptionCancelledEvent) {
|
||||
|
||||
@@ -7,18 +7,24 @@ import { SubscriptionExpiredEventHandler } from './SubscriptionExpiredEventHandl
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { Result } from '../Core/Result'
|
||||
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||
|
||||
describe('SubscriptionExpiredEventHandler', () => {
|
||||
let event: SubscriptionExpiredEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let saveRevenueModification: SaveRevenueModification
|
||||
|
||||
const createHandler = () => new SubscriptionExpiredEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore)
|
||||
const createHandler = () =>
|
||||
new SubscriptionExpiredEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, saveRevenueModification)
|
||||
|
||||
beforeEach(() => {
|
||||
event = {} as jest.Mocked<SubscriptionExpiredEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.type = 'SUBSCRIPTION_EXPIRED'
|
||||
event.payload = {
|
||||
subscriptionId: 1,
|
||||
userEmail: 'test@test.com',
|
||||
@@ -26,6 +32,9 @@ describe('SubscriptionExpiredEventHandler', () => {
|
||||
timestamp: 1,
|
||||
offline: false,
|
||||
totalActiveSubscriptionsCount: 123,
|
||||
userExistingSubscriptionsCount: 2,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
@@ -36,6 +45,9 @@ describe('SubscriptionExpiredEventHandler', () => {
|
||||
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.setMeasure = jest.fn()
|
||||
|
||||
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||
})
|
||||
|
||||
it('should update analytics and statistics', async () => {
|
||||
@@ -43,5 +55,6 @@ describe('SubscriptionExpiredEventHandler', () => {
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalled()
|
||||
expect(statisticsStore.setMeasure).toHaveBeenCalled()
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,10 +4,14 @@ import { inject, injectable } from 'inversify'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Email } from '../Common/Email'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
|
||||
@injectable()
|
||||
export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface {
|
||||
@@ -15,10 +19,11 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||
) {}
|
||||
|
||||
async handle(event: SubscriptionExpiredEvent): Promise<void> {
|
||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
await this.analyticsStore.markActivity(
|
||||
[AnalyticsActivity.SubscriptionExpired, AnalyticsActivity.ExistingCustomersChurn],
|
||||
analyticsId,
|
||||
@@ -30,5 +35,16 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
|
||||
event.payload.totalActiveSubscriptionsCount,
|
||||
[Period.Today, Period.ThisWeek, Period.ThisMonth, Period.ThisYear],
|
||||
)
|
||||
|
||||
await this.saveRevenueModification.execute({
|
||||
billingFrequency: event.payload.billingFrequency,
|
||||
eventType: SubscriptionEventType.create(event.type).getValue(),
|
||||
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
|
||||
payedAmount: event.payload.payAmount,
|
||||
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||
subscriptionId: event.payload.subscriptionId,
|
||||
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||
userUuid,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,18 +10,24 @@ import { SubscriptionRefundedEventHandler } from './SubscriptionRefundedEventHan
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { Period } from '../Time/Period'
|
||||
import { Result } from '../Core/Result'
|
||||
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
|
||||
describe('SubscriptionRefundedEventHandler', () => {
|
||||
let event: SubscriptionRefundedEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let saveRevenueModification: SaveRevenueModification
|
||||
|
||||
const createHandler = () => new SubscriptionRefundedEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore)
|
||||
const createHandler = () =>
|
||||
new SubscriptionRefundedEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, saveRevenueModification)
|
||||
|
||||
beforeEach(() => {
|
||||
event = {} as jest.Mocked<SubscriptionRefundedEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.type = 'SUBSCRIPTION_REFUNDED'
|
||||
event.payload = {
|
||||
subscriptionId: 1,
|
||||
userEmail: 'test@test.com',
|
||||
@@ -30,6 +36,8 @@ describe('SubscriptionRefundedEventHandler', () => {
|
||||
offline: false,
|
||||
userExistingSubscriptionsCount: 3,
|
||||
totalActiveSubscriptionsCount: 1,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
@@ -41,6 +49,9 @@ describe('SubscriptionRefundedEventHandler', () => {
|
||||
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.setMeasure = jest.fn()
|
||||
|
||||
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||
})
|
||||
|
||||
it('should mark churn for new customer', async () => {
|
||||
@@ -56,6 +67,8 @@ describe('SubscriptionRefundedEventHandler', () => {
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.NewCustomersChurn], 3, [
|
||||
Period.ThisMonth,
|
||||
])
|
||||
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should mark churn for existing customer', async () => {
|
||||
|
||||
@@ -4,10 +4,14 @@ import { inject, injectable } from 'inversify'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Email } from '../Common/Email'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
|
||||
@injectable()
|
||||
export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface {
|
||||
@@ -15,10 +19,11 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||
) {}
|
||||
|
||||
async handle(event: SubscriptionRefundedEvent): Promise<void> {
|
||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRefunded], analyticsId, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
@@ -26,6 +31,17 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
|
||||
])
|
||||
|
||||
await this.markChurnActivity(analyticsId, event)
|
||||
|
||||
await this.saveRevenueModification.execute({
|
||||
billingFrequency: event.payload.billingFrequency,
|
||||
eventType: SubscriptionEventType.create(event.type).getValue(),
|
||||
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
|
||||
payedAmount: event.payload.payAmount,
|
||||
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||
subscriptionId: event.payload.subscriptionId,
|
||||
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||
userUuid,
|
||||
})
|
||||
}
|
||||
|
||||
private async markChurnActivity(analyticsId: number, event: SubscriptionRefundedEvent): Promise<void> {
|
||||
|
||||
@@ -6,17 +6,23 @@ import { SubscriptionRenewedEvent } from '@standardnotes/domain-events'
|
||||
import { SubscriptionRenewedEventHandler } from './SubscriptionRenewedEventHandler'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||
import { Result } from '../Core/Result'
|
||||
|
||||
describe('SubscriptionRenewedEventHandler', () => {
|
||||
let event: SubscriptionRenewedEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let saveRevenueModification: SaveRevenueModification
|
||||
|
||||
const createHandler = () => new SubscriptionRenewedEventHandler(getUserAnalyticsId, analyticsStore)
|
||||
const createHandler = () =>
|
||||
new SubscriptionRenewedEventHandler(getUserAnalyticsId, analyticsStore, saveRevenueModification)
|
||||
|
||||
beforeEach(() => {
|
||||
event = {} as jest.Mocked<SubscriptionRenewedEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.type = 'SUBSCRIPTION_RENEWED'
|
||||
event.payload = {
|
||||
subscriptionId: 1,
|
||||
userEmail: 'test@test.com',
|
||||
@@ -24,6 +30,8 @@ describe('SubscriptionRenewedEventHandler', () => {
|
||||
subscriptionExpiresAt: 2,
|
||||
timestamp: 1,
|
||||
offline: false,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
@@ -32,6 +40,9 @@ describe('SubscriptionRenewedEventHandler', () => {
|
||||
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
|
||||
analyticsStore.markActivity = jest.fn()
|
||||
analyticsStore.unmarkActivity = jest.fn()
|
||||
|
||||
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||
})
|
||||
|
||||
it('should track subscription renewed statistics', async () => {
|
||||
@@ -39,5 +50,6 @@ describe('SubscriptionRenewedEventHandler', () => {
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalled()
|
||||
expect(analyticsStore.unmarkActivity).toHaveBeenCalled()
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,16 +6,21 @@ import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyti
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { Email } from '../Common/Email'
|
||||
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||
|
||||
@injectable()
|
||||
export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||
) {}
|
||||
|
||||
async handle(event: SubscriptionRenewedEvent): Promise<void> {
|
||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRenewed], analyticsId, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
@@ -26,5 +31,16 @@ export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterf
|
||||
analyticsId,
|
||||
[Period.Today, Period.ThisWeek, Period.ThisMonth],
|
||||
)
|
||||
|
||||
await this.saveRevenueModification.execute({
|
||||
billingFrequency: event.payload.billingFrequency,
|
||||
eventType: SubscriptionEventType.create(event.type).getValue(),
|
||||
newSubscriber: false,
|
||||
payedAmount: event.payload.payAmount,
|
||||
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||
subscriptionId: event.payload.subscriptionId,
|
||||
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||
userUuid,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ export class RevenueModificationMap implements MapInterface<RevenueModification,
|
||||
subscription,
|
||||
eventType: SubscriptionEventType.create(persistence.eventType).getValue(),
|
||||
previousMonthlyRevenue: previousMonthlyRevenueOrError.getValue(),
|
||||
createdAt: persistence.createdAt,
|
||||
},
|
||||
new UniqueEntityId(persistence.uuid),
|
||||
)
|
||||
@@ -55,6 +56,7 @@ export class RevenueModificationMap implements MapInterface<RevenueModification,
|
||||
persistence.subscriptionPlan = subscription.props.planName.value
|
||||
persistence.userEmail = user.props.email.value
|
||||
persistence.userUuid = user.id.toString()
|
||||
persistence.createdAt = domain.props.createdAt
|
||||
|
||||
return persistence
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ describe('RevenueModification', () => {
|
||||
|
||||
it('should create an aggregate for purchased subscription', () => {
|
||||
const revenueModification = RevenueModification.create({
|
||||
createdAt: 2,
|
||||
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
|
||||
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
|
||||
subscription,
|
||||
@@ -36,7 +37,7 @@ describe('RevenueModification', () => {
|
||||
|
||||
it('should create an aggregate for subscription expired', () => {
|
||||
const revenueModification = RevenueModification.create({
|
||||
createdAt: new Date(1),
|
||||
createdAt: 1,
|
||||
eventType: SubscriptionEventType.create('SUBSCRIPTION_EXPIRED').getValue(),
|
||||
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
|
||||
subscription,
|
||||
@@ -49,6 +50,7 @@ describe('RevenueModification', () => {
|
||||
|
||||
it('should create an aggregate for subscription cancelled', () => {
|
||||
const revenueModification = RevenueModification.create({
|
||||
createdAt: 2,
|
||||
eventType: SubscriptionEventType.create('SUBSCRIPTION_CANCELLED').getValue(),
|
||||
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
|
||||
subscription,
|
||||
|
||||
@@ -9,15 +9,7 @@ export class RevenueModification extends Aggregate<RevenueModificationProps> {
|
||||
}
|
||||
|
||||
static create(props: RevenueModificationProps, id?: UniqueEntityId): RevenueModification {
|
||||
const revenueModification = new RevenueModification(
|
||||
{
|
||||
...props,
|
||||
createdAt: props.createdAt ? props.createdAt : new Date(),
|
||||
},
|
||||
id,
|
||||
)
|
||||
|
||||
return revenueModification
|
||||
return new RevenueModification(props, id)
|
||||
}
|
||||
|
||||
get newMonthlyRevenue(): MonthlyRevenue {
|
||||
@@ -27,6 +19,7 @@ export class RevenueModification extends Aggregate<RevenueModificationProps> {
|
||||
switch (this.props.eventType.value) {
|
||||
case 'SUBSCRIPTION_PURCHASED':
|
||||
case 'SUBSCRIPTION_RENEWED':
|
||||
case 'SUBSCRIPTION_DATA_MIGRATED':
|
||||
revenue = subscription.props.payedAmount / subscription.props.billingFrequency
|
||||
break
|
||||
case 'SUBSCRIPTION_EXPIRED':
|
||||
|
||||
@@ -8,5 +8,5 @@ export interface RevenueModificationProps {
|
||||
subscription: Subscription
|
||||
eventType: SubscriptionEventType
|
||||
previousMonthlyRevenue: MonthlyRevenue
|
||||
createdAt?: Date
|
||||
createdAt: number
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProp
|
||||
'SUBSCRIPTION_EXPIRED',
|
||||
'SUBSCRIPTION_REFUNDED',
|
||||
'SUBSCRIPTION_CANCELLED',
|
||||
'SUBSCRIPTION_DATA_MIGRATED',
|
||||
].includes(subscriptionEventType)
|
||||
) {
|
||||
return Result.fail<SubscriptionEventType>(`Invalid subscription event type ${subscriptionEventType}`)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { Email } from '../../Common/Email'
|
||||
import { Uuid } from '../../Common/Uuid'
|
||||
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
|
||||
@@ -13,8 +15,9 @@ import { SaveRevenueModification } from './SaveRevenueModification'
|
||||
describe('SaveRevenueModification', () => {
|
||||
let revenueModificationRepository: RevenueModificationRepositoryInterface
|
||||
let previousMonthlyRevenue: RevenueModification
|
||||
let timer: TimerInterface
|
||||
|
||||
const createUseCase = () => new SaveRevenueModification(revenueModificationRepository)
|
||||
const createUseCase = () => new SaveRevenueModification(revenueModificationRepository, timer)
|
||||
|
||||
beforeEach(() => {
|
||||
previousMonthlyRevenue = {
|
||||
@@ -24,6 +27,9 @@ describe('SaveRevenueModification', () => {
|
||||
revenueModificationRepository = {} as jest.Mocked<RevenueModificationRepositoryInterface>
|
||||
revenueModificationRepository.findLastByUserUuid = jest.fn().mockReturnValue(previousMonthlyRevenue)
|
||||
revenueModificationRepository.save = jest.fn()
|
||||
|
||||
timer = {} as jest.Mocked<TimerInterface>
|
||||
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
|
||||
})
|
||||
|
||||
it('should persist a revenue modification', async () => {
|
||||
|
||||
@@ -9,12 +9,14 @@ import { User } from '../../User/User'
|
||||
import { Result } from '../../Core/Result'
|
||||
import { DomainUseCaseInterface } from '../DomainUseCaseInterface'
|
||||
import { SaveRevenueModificationDTO } from './SaveRevenueModificationDTO'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
@injectable()
|
||||
export class SaveRevenueModification implements DomainUseCaseInterface<RevenueModification> {
|
||||
constructor(
|
||||
@inject(TYPES.RevenueModificationRepository)
|
||||
private revenueModificationRepository: RevenueModificationRepositoryInterface,
|
||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||
) {}
|
||||
|
||||
async execute(dto: SaveRevenueModificationDTO): Promise<Result<RevenueModification>> {
|
||||
@@ -45,6 +47,7 @@ export class SaveRevenueModification implements DomainUseCaseInterface<RevenueMo
|
||||
subscription,
|
||||
user,
|
||||
previousMonthlyRevenue,
|
||||
createdAt: this.timer.getTimestampInMicroseconds(),
|
||||
})
|
||||
|
||||
await this.revenueModificationRepository.save(revenueModification)
|
||||
|
||||
@@ -56,4 +56,10 @@ export class TypeORMRevenueModification {
|
||||
name: 'new_mrr',
|
||||
})
|
||||
declare newMonthlyRevenue: number
|
||||
|
||||
@Column({
|
||||
name: 'created_at',
|
||||
type: 'bigint',
|
||||
})
|
||||
declare createdAt: number
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.37.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.4...@standardnotes/api-gateway@1.37.5) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.37.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.3...@standardnotes/api-gateway@1.37.4) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.37.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.2...@standardnotes/api-gateway@1.37.3) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.37.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.1...@standardnotes/api-gateway@1.37.2) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.37.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.0...@standardnotes/api-gateway@1.37.1) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.37.1",
|
||||
"version": "1.37.5",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.59.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.58.0...@standardnotes/auth-server@1.59.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription canceled ([52a257a](https://github.com/standardnotes/server/commit/52a257abb16034134a50474fbbb2493a00c58b99))
|
||||
|
||||
# [1.58.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.57.0...@standardnotes/auth-server@1.58.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription refunded ([0f65c05](https://github.com/standardnotes/server/commit/0f65c051abcff805e920f91d338e5fadda7905a9))
|
||||
|
||||
# [1.57.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.56.0...@standardnotes/auth-server@1.57.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription expired ([5c3db2c](https://github.com/standardnotes/server/commit/5c3db2cb29a929e44b63eb8226ce4ad1d14f8a99))
|
||||
|
||||
# [1.56.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.55.0...@standardnotes/auth-server@1.56.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription renewed ([cdb7fcf](https://github.com/standardnotes/server/commit/cdb7fcf8311fecfabe3ef9eb656cd6ec57b87de0))
|
||||
|
||||
# [1.55.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.54.0...@standardnotes/auth-server@1.55.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.55.0",
|
||||
"version": "1.59.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -40,6 +40,9 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||
subscriptionEndsAt: 2,
|
||||
subscriptionUpdatedAt: 2,
|
||||
lastPayedAt: 1,
|
||||
userExistingSubscriptionsCount: 1,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@ describe('SubscriptionExpiredEventHandler', () => {
|
||||
timestamp,
|
||||
offline: false,
|
||||
totalActiveSubscriptionsCount: 123,
|
||||
userExistingSubscriptionsCount: 2,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
|
||||
@@ -74,6 +74,8 @@ describe('SubscriptionRefundedEventHandler', () => {
|
||||
offline: false,
|
||||
userExistingSubscriptionsCount: 3,
|
||||
totalActiveSubscriptionsCount: 1,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
|
||||
@@ -81,6 +81,8 @@ describe('SubscriptionRenewedEventHandler', () => {
|
||||
subscriptionExpiresAt,
|
||||
timestamp,
|
||||
offline: false,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.18](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.17...@standardnotes/domain-events-infra@1.9.18) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.9.17](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.16...@standardnotes/domain-events-infra@1.9.17) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.9.16](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.15...@standardnotes/domain-events-infra@1.9.16) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.9.15](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.14...@standardnotes/domain-events-infra@1.9.15) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
## [1.9.14](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.13...@standardnotes/domain-events-infra@1.9.14) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/domain-events-infra
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.9.14",
|
||||
"version": "1.9.18",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.83.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.82.0...@standardnotes/domain-events@2.83.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription canceled ([52a257a](https://github.com/standardnotes/server/commit/52a257abb16034134a50474fbbb2493a00c58b99))
|
||||
|
||||
# [2.82.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.81.0...@standardnotes/domain-events@2.82.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription refunded ([0f65c05](https://github.com/standardnotes/server/commit/0f65c051abcff805e920f91d338e5fadda7905a9))
|
||||
|
||||
# [2.81.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.80.0...@standardnotes/domain-events@2.81.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription expired ([5c3db2c](https://github.com/standardnotes/server/commit/5c3db2cb29a929e44b63eb8226ce4ad1d14f8a99))
|
||||
|
||||
# [2.80.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.79.0...@standardnotes/domain-events@2.80.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add saving revenue modifications upon subscription renewed ([cdb7fcf](https://github.com/standardnotes/server/commit/cdb7fcf8311fecfabe3ef9eb656cd6ec57b87de0))
|
||||
|
||||
# [2.79.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.78.1...@standardnotes/domain-events@2.79.0) (2022-11-09)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events",
|
||||
"version": "2.79.0",
|
||||
"version": "2.83.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -11,4 +11,7 @@ export interface SubscriptionCancelledEventPayload {
|
||||
timestamp: number
|
||||
offline: boolean
|
||||
replaced: boolean
|
||||
userExistingSubscriptionsCount: number
|
||||
billingFrequency: number
|
||||
payAmount: number
|
||||
}
|
||||
|
||||
@@ -7,4 +7,7 @@ export interface SubscriptionExpiredEventPayload {
|
||||
timestamp: number
|
||||
offline: boolean
|
||||
totalActiveSubscriptionsCount: number
|
||||
userExistingSubscriptionsCount: number
|
||||
billingFrequency: number
|
||||
payAmount: number
|
||||
}
|
||||
|
||||
@@ -8,4 +8,6 @@ export interface SubscriptionRefundedEventPayload {
|
||||
totalActiveSubscriptionsCount: number
|
||||
timestamp: number
|
||||
offline: boolean
|
||||
billingFrequency: number
|
||||
payAmount: number
|
||||
}
|
||||
|
||||
@@ -7,4 +7,6 @@ export interface SubscriptionRenewedEventPayload {
|
||||
subscriptionExpiresAt: number
|
||||
timestamp: number
|
||||
offline: boolean
|
||||
billingFrequency: number
|
||||
payAmount: number
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.13](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.12...@standardnotes/event-store@1.6.13) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.6.12](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.11...@standardnotes/event-store@1.6.12) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.6.11](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.10...@standardnotes/event-store@1.6.11) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.6.10](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.9...@standardnotes/event-store@1.6.10) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.6.9](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.8...@standardnotes/event-store@1.6.9) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.6.9",
|
||||
"version": "1.6.13",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.8.13](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.12...@standardnotes/files-server@1.8.13) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.8.12](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.11...@standardnotes/files-server@1.8.12) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.8.11](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.10...@standardnotes/files-server@1.8.11) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.8.10](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.9...@standardnotes/files-server@1.8.10) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.8.9](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.8...@standardnotes/files-server@1.8.9) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.8.9",
|
||||
"version": "1.8.13",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.13.14](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.13...@standardnotes/scheduler-server@1.13.14) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.13.13](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.12...@standardnotes/scheduler-server@1.13.13) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.13.12](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.11...@standardnotes/scheduler-server@1.13.12) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.13.11](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.10...@standardnotes/scheduler-server@1.13.11) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.13.10](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.9...@standardnotes/scheduler-server@1.13.10) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.13.10",
|
||||
"version": "1.13.14",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.11.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.11.4...@standardnotes/syncing-server@1.11.5) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.11.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.11.3...@standardnotes/syncing-server@1.11.4) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.11.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.11.2...@standardnotes/syncing-server@1.11.3) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.11.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.11.1...@standardnotes/syncing-server@1.11.2) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.11.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.11.0...@standardnotes/syncing-server@1.11.1) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.11.1",
|
||||
"version": "1.11.5",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.13](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.12...@standardnotes/websockets-server@1.4.13) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.4.12](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.11...@standardnotes/websockets-server@1.4.12) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.4.11](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.10...@standardnotes/websockets-server@1.4.11) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.4.10](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.9...@standardnotes/websockets-server@1.4.10) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.4.9](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.4.8...@standardnotes/websockets-server@1.4.9) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.4.9",
|
||||
"version": "1.4.13",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.17.13](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.12...@standardnotes/workspace-server@1.17.13) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.17.12](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.11...@standardnotes/workspace-server@1.17.12) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.17.11](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.10...@standardnotes/workspace-server@1.17.11) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.17.10](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.9...@standardnotes/workspace-server@1.17.10) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
## [1.17.9](https://github.com/standardnotes/server/compare/@standardnotes/workspace-server@1.17.8...@standardnotes/workspace-server@1.17.9) (2022-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/workspace-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/workspace-server",
|
||||
"version": "1.17.9",
|
||||
"version": "1.17.13",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user