Ghost/ghost/members-api/lib/repositories/event/index.js

223 lines
6.6 KiB
JavaScript
Raw Normal View History

module.exports = class EventRepository {
constructor({
MemberSubscribeEvent,
MemberPaymentEvent,
MemberStatusEvent,
MemberLoginEvent,
MemberPaidSubscriptionEvent,
logger
}) {
this._MemberSubscribeEvent = MemberSubscribeEvent;
this._MemberPaidSubscriptionEvent = MemberPaidSubscriptionEvent;
this._MemberPaymentEvent = MemberPaymentEvent;
this._MemberStatusEvent = MemberStatusEvent;
this._MemberLoginEvent = MemberLoginEvent;
this._logging = logger;
}
async registerPayment(data) {
await this._MemberPaymentEvent.add({
...data,
source: 'stripe'
});
}
async getNewsletterSubscriptionEvents(options = {}) {
options.withRelated = ['member'];
const {data: models, meta} = await this._MemberSubscribeEvent.findPage(options);
const data = models.map((data) => {
return {
type: 'newsletter_event',
data: data.toJSON(options)
};
});
return {
data,
meta
};
}
async getSubscriptionEvents(options = {}) {
options.withRelated = ['member'];
const {data: models, meta} = await this._MemberPaidSubscriptionEvent.findPage(options);
const data = models.map((data) => {
return {
type: 'subscription_event',
data: data.toJSON(options)
};
});
return {
data,
meta
};
}
async getPaymentEvents(options = {}) {
options.withRelated = ['member'];
const {data: models, meta} = await this._MemberPaymentEvent.findPage(options);
const data = models.map((data) => {
return {
type: 'payment_event',
data: data.toJSON(options)
};
});
return {
data,
meta
};
}
async getLoginEvents(options = {}) {
options.withRelated = ['member'];
const {data: models, meta} = await this._MemberLoginEvent.findPage(options);
const data = models.map((data) => {
return {
type: 'login_event',
data: data.toJSON(options)
};
});
return {
data,
meta
};
}
async getEventTimeline(options = {}) {
if (!options.limit) {
options.limit = 10;
}
const allEventPages = await Promise.all([
this.getNewsletterSubscriptionEvents(options),
this.getSubscriptionEvents(options),
this.getLoginEvents(options)
]);
const allEvents = allEventPages.reduce((allEvents, page) => allEvents.concat(page.data), []);
return allEvents.sort((a, b) => {
return new Date(b.data.created_at) - new Date(a.data.created_at);
}).slice(0, options.limit);
}
async getSubscriptions() {
const results = await this._MemberSubscribeEvent.findAll({
aggregateSubscriptionDeltas: true
});
const resultsJSON = results.toJSON();
const cumulativeResults = resultsJSON.reduce((cumulativeResults, result, index) => {
if (index === 0) {
return [{
date: result.date,
subscribed: result.subscribed_delta
}];
}
return cumulativeResults.concat([{
date: result.date,
subscribed: result.subscribed_delta + cumulativeResults[index - 1].subscribed
}]);
}, []);
return cumulativeResults;
}
async getMRR() {
const results = await this._MemberPaidSubscriptionEvent.findAll({
aggregateMRRDeltas: true
});
const resultsJSON = results.toJSON();
const cumulativeResults = resultsJSON.reduce((cumulativeResults, result) => {
if (!cumulativeResults[result.currency]) {
return {
...cumulativeResults,
[result.currency]: [{
date: result.date,
mrr: result.mrr_delta,
currency: result.currency
}]
};
}
return {
...cumulativeResults,
[result.currency]: cumulativeResults[result.currency].concat([{
date: result.date,
mrr: result.mrr_delta + cumulativeResults[result.currency].slice(-1)[0],
currency: result.currency
}])
};
}, {});
return cumulativeResults;
}
async getVolume() {
const results = await this._MemberPaymentEvent.findAll({
aggregatePaymentVolume: true
});
const resultsJSON = results.toJSON();
const cumulativeResults = resultsJSON.reduce((cumulativeResults, result) => {
if (!cumulativeResults[result.currency]) {
return {
...cumulativeResults,
[result.currency]: [{
date: result.date,
volume: result.volume_delta,
currency: result.currency
}]
};
}
return {
...cumulativeResults,
[result.currency]: cumulativeResults[result.currency].concat([{
date: result.date,
volume: result.volume_delta + cumulativeResults[result.currency].slice(-1)[0],
currency: result.currency
}])
};
}, {});
return cumulativeResults;
}
async getStatuses() {
const results = await this._MemberStatusEvent.findAll({
aggregateStatusCounts: true
});
const resultsJSON = results.toJSON();
const cumulativeResults = resultsJSON.reduce((cumulativeResults, result, index) => {
if (index === 0) {
return [{
date: result.date,
paid: result.paid_delta,
comped: result.comped_delta,
free: result.free_delta
}];
}
return cumulativeResults.concat([{
date: result.date,
paid: result.paid_delta + cumulativeResults[index - 1].paid,
comped: result.comped_delta + cumulativeResults[index - 1].comped,
free: result.free_delta + cumulativeResults[index - 1].free
}]);
}, []);
return cumulativeResults;
}
};