UNPKG

@sourceloop/ctrl-plane-subscription-service

Version:

Subscription management microservice for SaaS control plane.

391 lines 16.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SubscriptionController = void 0; const tslib_1 = require("tslib"); const repository_1 = require("@loopback/repository"); const rest_1 = require("@loopback/rest"); const moment_1 = tslib_1.__importDefault(require("moment")); const models_1 = require("../models"); const repositories_1 = require("../repositories"); const loopback4_authorization_1 = require("loopback4-authorization"); const loopback4_authentication_1 = require("loopback4-authentication"); const permissions_1 = require("../permissions"); const core_1 = require("@sourceloop/core"); const enums_1 = require("../enums"); const basePath = '/subscriptions'; const DATE_FORMAT = 'YYYY-MM-DD'; const description = 'Array of Subscription model instances'; let SubscriptionController = class SubscriptionController { constructor(subscriptionRepository, planRepository, billingCycleRepository) { this.subscriptionRepository = subscriptionRepository; this.planRepository = planRepository; this.billingCycleRepository = billingCycleRepository; } async create(subscription) { const plan = await this.planRepository.findById(subscription.planId); const billingCycle = await this.billingCycleRepository.findById(plan.billingCycleId); const startDate = (0, moment_1.default)().format(DATE_FORMAT); const endDate = (0, moment_1.default)() .add(billingCycle.duration, this._unitMap(billingCycle.durationUnit)) .format(DATE_FORMAT); return this.subscriptionRepository.create({ ...subscription, startDate, endDate, }); } _unitMap(durationUnit) { switch (durationUnit) { case 'month': return 'M'; case 'year': return 'y'; case 'week': return 'week'; default: return 'days'; } } async count(where) { return this.subscriptionRepository.count(where); } async find(filter) { return this.subscriptionRepository.find(filter); } async expireSoonSubscription(filter) { const daysRemaining = 7; const subscriptions = await this.subscriptionRepository.find({ where: { status: enums_1.SubscriptionStatus.ACTIVE }, }); const expiringSoonSubscriptionObj = []; for (const subscription of subscriptions) { // check for if less then 7 days remaining and send notification if ((0, moment_1.default)(subscription.endDate).isBefore((0, moment_1.default)().add(daysRemaining, 'days')) && (0, moment_1.default)(subscription.endDate).isAfter((0, moment_1.default)())) { const daysRemainingToExpiry = (0, moment_1.default)(subscription.endDate).diff((0, moment_1.default)(), 'days'); expiringSoonSubscriptionObj.push({ id: subscription.id, daysRemainingToExpiry, subscriberId: subscription.subscriberId, }); } } return expiringSoonSubscriptionObj; } async expiredSubscription(dayCount, filter) { const subscriptions = await this.subscriptionRepository.find({ where: { status: enums_1.SubscriptionStatus.ACTIVE }, }); const markSubscriptionsAsExpiredPromises = []; for (const subscription of subscriptions) { // check for if subscription is expired if ((0, moment_1.default)(subscription.endDate).isBefore((0, moment_1.default)())) { markSubscriptionsAsExpiredPromises.push(this.subscriptionRepository.updateById(subscription.id, { status: enums_1.SubscriptionStatus.EXPIRED, })); } } await Promise.all(markSubscriptionsAsExpiredPromises); // calculate date before dayCount number of days from current date const range = (0, moment_1.default)().subtract(dayCount, 'days').format(DATE_FORMAT); const expiredSubscriptionWithInRange = []; const expiredSubscription = await this.subscriptionRepository.find({ where: { status: enums_1.SubscriptionStatus.EXPIRED }, }); for (const subscription of expiredSubscription) { if ((0, moment_1.default)(subscription.endDate).isAfter(range)) { expiredSubscriptionWithInRange.push({ subscriptionId: subscription.id, subscriberId: subscription.subscriberId, }); } } return expiredSubscriptionWithInRange; } async updateAll(subscription, where) { return this.subscriptionRepository.updateAll(subscription, where); } async findById(id, filter) { return this.subscriptionRepository.findById(id, filter); } async updateById(id, subscription) { await this.subscriptionRepository.updateById(id, subscription); } async replaceById(id, subscription) { await this.subscriptionRepository.replaceById(id, subscription); } async deleteById(id) { await this.subscriptionRepository.deleteById(id); } }; exports.SubscriptionController = SubscriptionController; tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.CreateSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.post)(basePath, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description: 'Subscription model instance', content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.Subscription) }, }, }, }, }), tslib_1.__param(0, (0, rest_1.requestBody)({ content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { title: 'NewSubscription', exclude: ['id', 'startDate', 'endDate'], }), }, }, })), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "create", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.ViewSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.get)(`${basePath}/count`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description: 'Subscription model count', content: { 'application/json': { schema: repository_1.CountSchema } }, }, }, }), tslib_1.__param(0, rest_1.param.where(models_1.Subscription)), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "count", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.ViewSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.get)(basePath, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description, content: { 'application/json': { schema: { type: 'array', items: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { includeRelations: true }), }, }, }, }, }, }), tslib_1.__param(0, rest_1.param.filter(models_1.Subscription)), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "find", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.ViewSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.get)(`${basePath}/expire-soon`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description, content: { 'application/json': { schema: { type: 'array', items: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { includeRelations: true }), }, }, }, }, }, }), tslib_1.__param(0, rest_1.param.filter(models_1.Subscription)), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "expireSoonSubscription", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.ViewSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.get)(`${basePath}/expired`, { description: 'api that will return newly expired subscription', security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description, content: { 'application/json': { schema: { type: 'array', items: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { includeRelations: true }), }, }, }, }, }, }), tslib_1.__param(0, rest_1.param.header.number('days')), tslib_1.__param(1, rest_1.param.filter(models_1.Subscription)), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Number, Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "expiredSubscription", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.UpdateSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.patch)(basePath, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description: 'Subscription PATCH success count', content: { 'application/json': { schema: repository_1.CountSchema } }, }, }, }), tslib_1.__param(0, (0, rest_1.requestBody)({ content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { partial: true }), }, }, })), tslib_1.__param(1, rest_1.param.where(models_1.Subscription)), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [models_1.Subscription, Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "updateAll", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.ViewSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.get)(`${basePath}/{id}`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [200 /* STATUS_CODE.OK */]: { description: 'Subscription model instance', content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { includeRelations: true }), }, }, }, }, }), tslib_1.__param(0, rest_1.param.path.string('id')), tslib_1.__param(1, rest_1.param.filter(models_1.Subscription, { exclude: 'where' })), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String, Object]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "findById", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.UpdateSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.patch)(`${basePath}/{id}`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [204 /* STATUS_CODE.NO_CONTENT */]: { description: 'Subscription PATCH success', }, }, }), tslib_1.__param(0, rest_1.param.path.string('id')), tslib_1.__param(1, (0, rest_1.requestBody)({ content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.Subscription, { partial: true }), }, }, })), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String, models_1.Subscription]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "updateById", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.UpdateSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.put)(`${basePath}/{id}`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [204 /* STATUS_CODE.NO_CONTENT */]: { description: 'Subscription PUT success', }, }, }), tslib_1.__param(0, rest_1.param.path.string('id')), tslib_1.__param(1, (0, rest_1.requestBody)()), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String, models_1.Subscription]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "replaceById", null); tslib_1.__decorate([ (0, loopback4_authorization_1.authorize)({ permissions: [permissions_1.PermissionKey.DeleteSubscription], }), (0, loopback4_authentication_1.authenticate)("bearer" /* STRATEGY.BEARER */, { passReqToCallback: true, }), (0, rest_1.del)(`${basePath}/{id}`, { security: core_1.OPERATION_SECURITY_SPEC, responses: { [204 /* STATUS_CODE.NO_CONTENT */]: { description: 'Subscription DELETE success', }, }, }), tslib_1.__param(0, rest_1.param.path.string('id')), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String]), tslib_1.__metadata("design:returntype", Promise) ], SubscriptionController.prototype, "deleteById", null); exports.SubscriptionController = SubscriptionController = tslib_1.__decorate([ tslib_1.__param(0, (0, repository_1.repository)(repositories_1.SubscriptionRepository)), tslib_1.__param(1, (0, repository_1.repository)(repositories_1.PlanRepository)), tslib_1.__param(2, (0, repository_1.repository)(repositories_1.BillingCycleRepository)), tslib_1.__metadata("design:paramtypes", [repositories_1.SubscriptionRepository, repositories_1.PlanRepository, repositories_1.BillingCycleRepository]) ], SubscriptionController); //# sourceMappingURL=subscription.controller.js.map