Ghost/core/server/models/member-status-event.js
Fabien 'egg' O'Carroll f4cb5c57c6
Updated members_status_events table (#12647)
refs https://github.com/TryGhost/Ghost/issues/12602

* Updated members_status_events table

By replacing the `status` column with a `from_status` and `to_status`
column, we are able to track the changes between multiple statuses
easier, and accumulate the data. e.g. the delta of paid members in a
given time range is the sum of the `to_status` columns set to 'paid'
minus the sum of the `from_status` columns set to 'paid' within that
time range

* Updated MEGA to handle addition of 'comped' status

With the addition of the 'comped' status, we need to ensure that MEGA
will still send emails to the correct recipients. I've opted to use an
"inverse" filter, as that is the intention of the free/paid split in
MEGA - as far as MEGA is concerned, "free" is the opposite of "paid"

* Updated customQuery for MemberStatusEvent

With the `status` column replaced with `from_status` and `to_status`
this allows us to fix and update the customQuery to correctly accumulate
the data into deltas over time, broken down by day.

* Populated members_status_events table

As the table will be used to generate deltas, we need to backfill the
data so that existing sites will be able to sum up the deltas and
calculate correct data.

The assumptions used in backfilling is that a Member's current status,
is their only status.
2021-02-16 10:38:36 +00:00

51 lines
1.8 KiB
JavaScript

const errors = require('@tryghost/errors');
const ghostBookshelf = require('./base');
const MemberStatusEvent = ghostBookshelf.Model.extend({
tableName: 'members_status_events',
customQuery(qb, options) {
if (options.aggregateStatusCounts) {
if (options.limit || options.filter) {
throw new errors.IncorrectUsageError('aggregateStatusCounts does not work when passed a filter or limit');
}
const knex = ghostBookshelf.knex;
return qb.clear('select')
.select(knex.raw('DATE(created_at) as date'))
.select(knex.raw(`SUM(
CASE WHEN to_status='paid' THEN 1
CASE WHEN from_status='paid' THEN -1
ELSE 0 END
) as paid_delta`))
.select(knex.raw(`SUM(
CASE WHEN to_status='comped' THEN 1
CASE WHEN from_status='comped' THEN -1
ELSE 0 END
) as comped_delta`))
.select(knex.raw(`SUM(
CASE WHEN to_status='free' THEN 1
CASE WHEN from_status='free' THEN -1
ELSE 0 END
) as free_delta`))
.groupByRaw('DATE(created_at)')
.orderByRaw('DATE(created_at)');
}
}
}, {
async edit() {
throw new errors.IncorrectUsageError('Cannot edit MemberStatusEvent');
},
async destroy() {
throw new errors.IncorrectUsageError('Cannot destroy MemberStatusEvent');
}
});
const MemberStatusEvents = ghostBookshelf.Collection.extend({
model: MemberStatusEvent
});
module.exports = {
MemberStatusEvent: ghostBookshelf.model('MemberStatusEvent', MemberStatusEvent),
MemberStatusEvents: ghostBookshelf.collection('MemberStatusEvents', MemberStatusEvents)
};