From e1b3b38bcde76208371e9bb907f04f0ae201ce70 Mon Sep 17 00:00:00 2001 From: Fabien 'egg' O'Carroll Date: Thu, 18 Feb 2021 11:16:39 +0000 Subject: [PATCH] Added initial support for event timelines refs https://github.com/TryGhost/Ghost/issues/12602 This adds initial support for sitewide event timelines --- ghost/members-api/index.js | 1 + .../lib/repositories/event/index.js | 88 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/ghost/members-api/index.js b/ghost/members-api/index.js index 1ab22c98fe..c9f91b6d28 100644 --- a/ghost/members-api/index.js +++ b/ghost/members-api/index.js @@ -83,6 +83,7 @@ module.exports = function MembersApi({ MemberPaidSubscriptionEvent, MemberPaymentEvent, MemberStatusEvent, + MemberLoginEvent, MemberEmailChangeEvent }); diff --git a/ghost/members-api/lib/repositories/event/index.js b/ghost/members-api/lib/repositories/event/index.js index 3bff1b5bce..a12c03deaa 100644 --- a/ghost/members-api/lib/repositories/event/index.js +++ b/ghost/members-api/lib/repositories/event/index.js @@ -3,6 +3,7 @@ module.exports = class EventRepository { MemberSubscribeEvent, MemberPaymentEvent, MemberStatusEvent, + MemberLoginEvent, MemberPaidSubscriptionEvent, logger }) { @@ -10,6 +11,7 @@ module.exports = class EventRepository { this._MemberPaidSubscriptionEvent = MemberPaidSubscriptionEvent; this._MemberPaymentEvent = MemberPaymentEvent; this._MemberStatusEvent = MemberStatusEvent; + this._MemberLoginEvent = MemberLoginEvent; this._logging = logger; } @@ -20,6 +22,92 @@ module.exports = class EventRepository { }); } + 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