diff --git a/ghost/members-api/lib/repositories/MemberRepository.js b/ghost/members-api/lib/repositories/MemberRepository.js index 44e8c6f906..6c395a38b0 100644 --- a/ghost/members-api/lib/repositories/MemberRepository.js +++ b/ghost/members-api/lib/repositories/MemberRepository.js @@ -1025,9 +1025,21 @@ module.exports = class MemberRepository { return 'inactive'; }; - let eventData = {}; - if (model) { + + const shouldBeDeleted = subscription.metadata && !!subscription.metadata.ghost_migrated_to && subscription.status === 'canceled'; + if (shouldBeDeleted) { + logging.warn(`Subscription ${subscriptionData.subscription_id} is marked for deletion, skipping linking.`); + + if (model) { + // Delete all paid subscription events manually for this subscription + // This is the only related event without a foreign key constraint + await this._MemberPaidSubscriptionEvent.query().where('subscription_id', model.id).delete().transacting(options.transacting); + + // Delete the subscription in the database because we don't want to show it in the UI or in our data calculations + await model.destroy(options); + } + } else if (model) { // CASE: Offer is already mapped against sub, don't overwrite it with NULL // Needed for trial offers, which don't have a stripe coupon/discount attached to sub if (!subscriptionData.offer_id) { @@ -1133,7 +1145,7 @@ module.exports = class MemberRepository { let memberProducts = (await member.related('products').fetch(options)).toJSON(); const oldMemberProducts = member.related('products').toJSON(); let status = memberProducts.length === 0 ? 'free' : 'comped'; - if (this.isActiveSubscriptionStatus(subscription.status)) { + if (!shouldBeDeleted && this.isActiveSubscriptionStatus(subscription.status)) { if (this.isComplimentarySubscription(subscription)) { status = 'comped'; } else {