mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-18 16:01:40 +03:00
Migrated members comped status to reflect subscriptions (#13285)
* Migrated members comped status to reflect subscriptions refs https://github.com/TryGhost/Team/issues/995 Due to a bug in subscription handling, members with Complimentary stripe subscriptions were incorrectly given a status of 'paid'. The goal of this migration is to fix existing broken members, and it will be accompanied by a fix which prevents the bug for future members. Since we are updating the status properties for members, we must ensure that we also update the relevant member_status_events entries too, so that we do not have incompatible sums between events and statuses. For example, if we were to use events to graph comped members over time, we would want the current count to match the query on statuses: `SELECT COUNT(*) FROM members WHERE status='comped';`
This commit is contained in:
parent
677dc1a59b
commit
a0a35df13b
@ -0,0 +1,70 @@
|
||||
const {chunk} = require('lodash');
|
||||
const {createTransactionalMigration} = require('../../utils');
|
||||
const logging = require('@tryghost/logging');
|
||||
|
||||
module.exports = createTransactionalMigration(async function up(knex) {
|
||||
const compedMemberIds = (await knex('members')
|
||||
.select('members.id')
|
||||
.innerJoin(
|
||||
'members_stripe_customers',
|
||||
'members.id',
|
||||
'members_stripe_customers.member_id'
|
||||
).innerJoin(
|
||||
'members_stripe_customers_subscriptions',
|
||||
function () {
|
||||
this.on(
|
||||
'members_stripe_customers.customer_id',
|
||||
'members_stripe_customers_subscriptions.customer_id'
|
||||
).onIn(
|
||||
'members_stripe_customers_subscriptions.status',
|
||||
['active', 'trialing', 'past_due', 'unpaid']
|
||||
);
|
||||
}
|
||||
).where(
|
||||
'members_stripe_customers_subscriptions.plan_nickname',
|
||||
'=',
|
||||
'Complimentary'
|
||||
).andWhere(
|
||||
'members.status',
|
||||
'!=',
|
||||
'comped'
|
||||
)).map(({id}) => id);
|
||||
|
||||
if (!compedMemberIds.length) {
|
||||
logging.warn('No Complimentary members found with incorrect status');
|
||||
return;
|
||||
} else {
|
||||
logging.info(`Found ${compedMemberIds.length} Complimentary members with the incorrect status`);
|
||||
}
|
||||
|
||||
// Umm? Well... The current version of SQLite3 bundled with Ghost supports
|
||||
// a maximum of 999 variables, we use one variable for the SET value
|
||||
// and so we're left with 998 for our WHERE IN clause values
|
||||
const chunkSize = 998;
|
||||
|
||||
const compedMemberIdChunks = chunk(compedMemberIds, chunkSize);
|
||||
|
||||
for (const compedMemberIdsChunk of compedMemberIdChunks) {
|
||||
await knex('members')
|
||||
.update('status', 'comped')
|
||||
.whereIn('id', compedMemberIdsChunk);
|
||||
}
|
||||
|
||||
for (const memberId of compedMemberIds) {
|
||||
const mostRecentStatusEvent = await knex('members_status_events')
|
||||
.select('*')
|
||||
.where('member_id', memberId)
|
||||
.orderBy('created_at', 'desc')
|
||||
.limit(1)
|
||||
.first();
|
||||
|
||||
if (!mostRecentStatusEvent) {
|
||||
logging.warn(`Could not find a status event for member ${memberId} - skipping this member`);
|
||||
} else if (mostRecentStatusEvent.to_status !== 'comped') {
|
||||
logging.info(`Updating members_status_event ${mostRecentStatusEvent.id}`);
|
||||
await knex('members_status_events')
|
||||
.update('to_status', 'comped')
|
||||
.where('id', mostRecentStatusEvent.id);
|
||||
}
|
||||
}
|
||||
}, async function down() {});
|
Loading…
Reference in New Issue
Block a user