fix: cleanup revision requests
This commit is contained in:
parent
c1805ee2ac
commit
7e8d7f6874
11 changed files with 0 additions and 186 deletions
|
@ -1,71 +0,0 @@
|
|||
import 'reflect-metadata'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
|
||||
import { UserSubscriptionRepositoryInterface } from '../src/Domain/Subscription/UserSubscriptionRepositoryInterface'
|
||||
import { SubscriptionPlanName } from '@standardnotes/domain-core'
|
||||
|
||||
const requestCleanup = async (
|
||||
userSubscriptionRepository: UserSubscriptionRepositoryInterface,
|
||||
domainEventFactory: DomainEventFactoryInterface,
|
||||
domainEventPublisher: DomainEventPublisherInterface,
|
||||
): Promise<void> => {
|
||||
const proSubscriptionPlan = SubscriptionPlanName.create(SubscriptionPlanName.NAMES.ProPlan).getValue()
|
||||
const plusSubscriptionPlan = SubscriptionPlanName.create(SubscriptionPlanName.NAMES.PlusPlan).getValue()
|
||||
|
||||
const totalSubscriptions = await userSubscriptionRepository.countByPlanName([
|
||||
proSubscriptionPlan,
|
||||
plusSubscriptionPlan,
|
||||
])
|
||||
|
||||
const limitPerPage = 100
|
||||
const numberOfPages = Math.ceil(totalSubscriptions / limitPerPage)
|
||||
for (let i = 0; i < numberOfPages; i++) {
|
||||
const subscriptions = await userSubscriptionRepository.findByPlanName(
|
||||
[proSubscriptionPlan, plusSubscriptionPlan],
|
||||
i * limitPerPage,
|
||||
limitPerPage,
|
||||
)
|
||||
|
||||
for (const subscription of subscriptions) {
|
||||
await domainEventPublisher.publish(
|
||||
domainEventFactory.createRevisionsCleanupRequestedEvent({
|
||||
userUuid: subscription.userUuid,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
void container.load().then((container) => {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const logger: Logger = container.get(TYPES.Auth_Logger)
|
||||
|
||||
logger.info('Starting revisions cleanup triggering...')
|
||||
|
||||
const domainEventFactory = container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory)
|
||||
const domainEventPublisher = container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher)
|
||||
const userSubscriptionRepository = container.get<UserSubscriptionRepositoryInterface>(
|
||||
TYPES.Auth_UserSubscriptionRepository,
|
||||
)
|
||||
|
||||
Promise.resolve(requestCleanup(userSubscriptionRepository, domainEventFactory, domainEventPublisher))
|
||||
.then(() => {
|
||||
logger.info('Finished revisions cleanup triggering')
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Failed to trigger revisions cleanup: ${(error as Error).message}`)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
|
@ -1,11 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
|
||||
|
||||
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/revisions_cleanup.js')))
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
|
||||
exports.default = index
|
|
@ -44,10 +44,6 @@ case "$COMMAND" in
|
|||
exec node docker/entrypoint-delete-accounts.js $FILE_NAME $MODE
|
||||
;;
|
||||
|
||||
'revisions-cleanup' )
|
||||
exec node docker/entrypoint-revisions-cleanup.js
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "[Docker] Unknown command"
|
||||
;;
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
SessionRefreshedEvent,
|
||||
AccountDeletionVerificationRequestedEvent,
|
||||
FileQuotaRecalculationRequestedEvent,
|
||||
RevisionsCleanupRequestedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
@ -35,22 +34,6 @@ import { KeyParamsData } from '@standardnotes/responses'
|
|||
@injectable()
|
||||
export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
constructor(@inject(TYPES.Auth_Timer) private timer: TimerInterface) {}
|
||||
|
||||
createRevisionsCleanupRequestedEvent(dto: { userUuid: string }): RevisionsCleanupRequestedEvent {
|
||||
return {
|
||||
type: 'REVISIONS_CLEANUP_REQUESTED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: dto.userUuid,
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: DomainEventService.Auth,
|
||||
},
|
||||
payload: dto,
|
||||
}
|
||||
}
|
||||
|
||||
createFileQuotaRecalculationRequestedEvent(dto: { userUuid: string }): FileQuotaRecalculationRequestedEvent {
|
||||
return {
|
||||
type: 'FILE_QUOTA_RECALCULATION_REQUESTED',
|
||||
|
|
|
@ -20,13 +20,11 @@ import {
|
|||
SessionRefreshedEvent,
|
||||
AccountDeletionVerificationRequestedEvent,
|
||||
FileQuotaRecalculationRequestedEvent,
|
||||
RevisionsCleanupRequestedEvent,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
|
||||
import { KeyParamsData } from '@standardnotes/responses'
|
||||
|
||||
export interface DomainEventFactoryInterface {
|
||||
createRevisionsCleanupRequestedEvent(dto: { userUuid: string }): RevisionsCleanupRequestedEvent
|
||||
createFileQuotaRecalculationRequestedEvent(dto: { userUuid: string }): FileQuotaRecalculationRequestedEvent
|
||||
createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent
|
||||
createEmailRequestedEvent(dto: {
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import { DomainEventInterface } from './DomainEventInterface'
|
||||
import { RevisionsCleanupRequestedEventPayload } from './RevisionsCleanupRequestedEventPayload'
|
||||
|
||||
export interface RevisionsCleanupRequestedEvent extends DomainEventInterface {
|
||||
type: 'REVISIONS_CLEANUP_REQUESTED'
|
||||
payload: RevisionsCleanupRequestedEventPayload
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export interface RevisionsCleanupRequestedEventPayload {
|
||||
userUuid: string
|
||||
}
|
|
@ -72,8 +72,6 @@ export * from './Event/PredicateVerifiedEvent'
|
|||
export * from './Event/PredicateVerifiedEventPayload'
|
||||
export * from './Event/RefundProcessedEvent'
|
||||
export * from './Event/RefundProcessedEventPayload'
|
||||
export * from './Event/RevisionsCleanupRequestedEvent'
|
||||
export * from './Event/RevisionsCleanupRequestedEventPayload'
|
||||
export * from './Event/RevisionsCopyRequestedEvent'
|
||||
export * from './Event/RevisionsCopyRequestedEventPayload'
|
||||
export * from './Event/SessionCreatedEvent'
|
||||
|
|
|
@ -162,7 +162,6 @@ import { SyncResponse } from '@standardnotes/grpc'
|
|||
import { SyncResponseGRPCMapper } from '../Mapping/gRPC/SyncResponseGRPCMapper'
|
||||
import { AccountDeletionVerificationRequestedEventHandler } from '../Domain/Handler/AccountDeletionVerificationRequestedEventHandler'
|
||||
import { SendEventToClients } from '../Domain/UseCase/Syncing/SendEventToClients/SendEventToClients'
|
||||
import { RevisionsCleanupRequestedEventHandler } from '../Domain/Handler/RevisionsCleanupRequestedEventHandler'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000
|
||||
|
@ -981,16 +980,6 @@ export class ContainerConfigLoader {
|
|||
container.get<Logger>(TYPES.Sync_Logger),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<RevisionsCleanupRequestedEventHandler>(TYPES.Sync_RevisionsCleanupRequestedEventHandler)
|
||||
.toConstantValue(
|
||||
new RevisionsCleanupRequestedEventHandler(
|
||||
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLItemRepository),
|
||||
container.get<DomainEventFactoryInterface>(TYPES.Sync_DomainEventFactory),
|
||||
container.get<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher),
|
||||
container.get<Logger>(TYPES.Sync_Logger),
|
||||
),
|
||||
)
|
||||
|
||||
// Services
|
||||
container.bind<ContentDecoderInterface>(TYPES.Sync_ContentDecoder).toDynamicValue(() => new ContentDecoder())
|
||||
|
@ -1019,7 +1008,6 @@ export class ContainerConfigLoader {
|
|||
'SHARED_VAULT_REMOVED',
|
||||
container.get<SharedVaultRemovedEventHandler>(TYPES.Sync_SharedVaultRemovedEventHandler),
|
||||
],
|
||||
['REVISIONS_CLEANUP_REQUESTED', container.get(TYPES.Sync_RevisionsCleanupRequestedEventHandler)],
|
||||
])
|
||||
if (!isConfiguredForHomeServer) {
|
||||
container
|
||||
|
|
|
@ -97,7 +97,6 @@ const TYPES = {
|
|||
Sync_SharedVaultFileUploadedEventHandler: Symbol.for('Sync_SharedVaultFileUploadedEventHandler'),
|
||||
Sync_SharedVaultFileMovedEventHandler: Symbol.for('Sync_SharedVaultFileMovedEventHandler'),
|
||||
Sync_SharedVaultRemovedEventHandler: Symbol.for('Sync_SharedVaultRemovedEventHandler'),
|
||||
Sync_RevisionsCleanupRequestedEventHandler: Symbol.for('Sync_RevisionsCleanupRequestedEventHandler'),
|
||||
// Services
|
||||
Sync_ContentDecoder: Symbol.for('Sync_ContentDecoder'),
|
||||
Sync_DomainEventPublisher: Symbol.for('Sync_DomainEventPublisher'),
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
import {
|
||||
RevisionsCleanupRequestedEvent,
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
|
||||
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
|
||||
|
||||
export class RevisionsCleanupRequestedEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
private itemRepository: ItemRepositoryInterface,
|
||||
private domainEventFactory: DomainEventFactoryInterface,
|
||||
private domainEventPublisher: DomainEventPublisherInterface,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async handle(event: RevisionsCleanupRequestedEvent): Promise<void> {
|
||||
const totalDeletedItems = await this.itemRepository.countAll({
|
||||
userUuid: event.payload.userUuid,
|
||||
deleted: true,
|
||||
})
|
||||
|
||||
this.logger.info(`Found ${totalDeletedItems} deleted items`, {
|
||||
userId: event.payload.userUuid,
|
||||
})
|
||||
|
||||
const limitPerPage = 100
|
||||
const numberOfPages = Math.ceil(totalDeletedItems / limitPerPage)
|
||||
|
||||
for (let i = 0; i < numberOfPages; i++) {
|
||||
const items = await this.itemRepository.findAll({
|
||||
userUuid: event.payload.userUuid,
|
||||
deleted: true,
|
||||
offset: i * limitPerPage,
|
||||
limit: limitPerPage,
|
||||
sortOrder: 'ASC',
|
||||
sortBy: 'created_at_timestamp',
|
||||
})
|
||||
|
||||
for (const item of items) {
|
||||
await this.domainEventPublisher.publish(
|
||||
this.domainEventFactory.createItemDeletedEvent({
|
||||
itemUuid: item.id.toString(),
|
||||
userUuid: item.props.userUuid.value,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.info(`Finished processing ${totalDeletedItems} deleted items`, {
|
||||
userId: event.payload.userUuid,
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue