Moved redirect handling outside of repository

no-issue

The redirect handling is more of an application concern that can happen
at the top level, rather than the lower level of the repository.
This commit is contained in:
Fabien O'Carroll 2021-10-05 16:24:47 +02:00
parent d4ed604cce
commit b3ed676e53
3 changed files with 69 additions and 8 deletions

View File

@ -1,12 +1,44 @@
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('./lib/events/OfferCodeChange');
const OfferRepository = require('./lib/OfferRepository'); const OfferRepository = require('./lib/OfferRepository');
const OffersAPI = require('./lib/OffersAPI'); const OffersAPI = require('./lib/OffersAPI');
class OffersModule { class OffersModule {
/** /**
* @param {OffersAPI} offersAPI * @param {OffersAPI} offersAPI
* @param {import('@tryghost/express-dynamic-redirects')} redirectManager
*/ */
constructor(offersAPI) { constructor(offersAPI, redirectManager) {
this.api = offersAPI; this.api = offersAPI;
this.redirectManager = redirectManager;
}
/**
* @returns {Promise<void>}
*/
async init() {
DomainEvents.subscribe(OfferCodeChangeEvent, (event) => {
if (event.data.previousCodes) {
for (const previousCode of event.data.previousCodes) {
this.redirectManager.removeRedirect(`/${previousCode}`);
}
}
this.redirectManager.addRedirect(
`/${event.data.currentCode}`,
`/#/portal/offers/${event.data.offerId}`,
{permanent: false}
);
});
const offers = await this.api.listOffers();
for (const offer of offers) {
this.redirectManager.addRedirect(
`/${offer.code}`,
`/#/portal/offers/${offer.id}`,
{permanent: false}
);
}
} }
/** /**
@ -18,9 +50,9 @@ class OffersModule {
* @returns {OffersModule} * @returns {OffersModule}
*/ */
static create(deps) { static create(deps) {
const repository = new OfferRepository(deps.OfferModel, deps.stripeAPIService, deps.redirectManager); const repository = new OfferRepository(deps.OfferModel, deps.stripeAPIService);
const offersAPI = new OffersAPI(repository); const offersAPI = new OffersAPI(repository);
return new OffersModule(offersAPI); return new OffersModule(offersAPI, deps.redirectManager);
} }
} }

View File

@ -1,3 +1,5 @@
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('./events/OfferCodeChange');
const Offer = require('./Offer'); const Offer = require('./Offer');
/** /**
@ -125,12 +127,12 @@ class OfferRepository {
}); });
if (offer.codeChanged || offer.isNew) { if (offer.codeChanged || offer.isNew) {
offer.oldCodes.forEach((code) => { const event = OfferCodeChangeEvent.create({
this.redirectManager.removeRedirect(code); offerId: offer.id,
}); previousCodes: offer.isNew ? null : offer.oldCodes,
this.redirectManager.addRedirect(`/${offer.code}`, `/#/portal/offers/${offer.id}`, { currentCode: offer.code
permanent: false
}); });
DomainEvents.dispatch(event);
} }
if (offer.isNew) { if (offer.isNew) {

View File

@ -0,0 +1,27 @@
/**
* @typedef {object} OfferCodeChangeEventData
* @prop {string} offerId
* @prop {string[]} previousCodes
* @prop {string} currentCode
*/
class OfferCodeChangeEvent {
/**
* @param {OfferCodeChangeEventData} data
* @param {Date} timestamp
*/
constructor(data, timestamp) {
this.data = data;
this.timestamp = timestamp;
}
/**
* @param {OfferCodeChangeEventData} data
* @param {Date} [timestamp]
*/
static create(data, timestamp) {
return new OfferCodeChangeEvent(data, timestamp || new Date);
}
}
module.exports = OfferCodeChangeEvent;