mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-27 22:49:56 -05:00
Backfilled missing offer redemptions (#20647)
ref
https://linear.app/tryghost/issue/ENG-1440/backfill-offer-redemption-data-with-a-migration
There was a bug that caused offer redemptions to not be recorded in the
database for some subscriptions that were created with an offer.
However, we still have the `offer_id` attached to the subscriptions, so
we are able to backfill the missing redemptions. The bug was fixed in
bf895e6e99
This commit only contains a migration, which queries for subscriptions
that have an `offer_id` but do not have any offer redemptions recorded,
and adds any missing redemptions to the `offer_redemptions` table.
This commit is contained in:
parent
f147167a29
commit
7522b74e1f
1 changed files with 64 additions and 0 deletions
|
@ -0,0 +1,64 @@
|
||||||
|
// For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
|
||||||
|
|
||||||
|
const logging = require('@tryghost/logging');
|
||||||
|
const DatabaseInfo = require('@tryghost/database-info');
|
||||||
|
const {default: ObjectID} = require('bson-objectid');
|
||||||
|
|
||||||
|
// For DML - data changes
|
||||||
|
const {createTransactionalMigration} = require('../../utils');
|
||||||
|
|
||||||
|
module.exports = createTransactionalMigration(
|
||||||
|
async function up(knex) {
|
||||||
|
// Backfill missing offer redemptions
|
||||||
|
try {
|
||||||
|
// Select all subscriptions that have an `offer_id` but don't have a matching row in the `offer_redemptions` table
|
||||||
|
logging.info('Selecting subscriptions with missing offer redemptions');
|
||||||
|
const result = await knex.raw(`
|
||||||
|
SELECT
|
||||||
|
mscs.id AS subscription_id,
|
||||||
|
mscs.offer_id,
|
||||||
|
mscs.start_date AS created_at,
|
||||||
|
m.id AS member_id
|
||||||
|
FROM
|
||||||
|
members_stripe_customers_subscriptions mscs
|
||||||
|
LEFT JOIN
|
||||||
|
offer_redemptions r ON r.subscription_id = mscs.id
|
||||||
|
INNER JOIN
|
||||||
|
members_stripe_customers msc ON mscs.customer_id = msc.customer_id
|
||||||
|
INNER JOIN
|
||||||
|
members m ON msc.member_id = m.id
|
||||||
|
WHERE
|
||||||
|
mscs.offer_id IS NOT NULL and r.id IS NULL;
|
||||||
|
`);
|
||||||
|
|
||||||
|
// knex.raw() returns a different result depending on the database. We need to handle either case
|
||||||
|
let rows = [];
|
||||||
|
if (DatabaseInfo.isSQLite(knex)) {
|
||||||
|
rows = result;
|
||||||
|
} else {
|
||||||
|
rows = result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the backfil
|
||||||
|
if (rows && rows.length > 0) {
|
||||||
|
logging.info(`Backfilling ${rows.length} offer redemptions`);
|
||||||
|
// Generate IDs for each row
|
||||||
|
const offerRedemptions = rows.map((row) => {
|
||||||
|
return {
|
||||||
|
id: (new ObjectID()).toHexString(),
|
||||||
|
...row
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// Batch insert rows into the offer_redemptions table
|
||||||
|
await knex.batchInsert('offer_redemptions', offerRedemptions, 1000);
|
||||||
|
} else {
|
||||||
|
logging.info('No offer redemptions to backfill');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logging.error(`Error backfilling offer redemptions: ${error.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async function down() {
|
||||||
|
// We don't want to un-backfill data, so do nothing here.
|
||||||
|
}
|
||||||
|
);
|
Loading…
Add table
Reference in a new issue