diff --git a/services/orchestrator-service/README.md b/services/orchestrator-service/README.md index 57ead03..0b1e17f 100644 --- a/services/orchestrator-service/README.md +++ b/services/orchestrator-service/README.md @@ -73,6 +73,7 @@ This microservice provides following loopback services and providers which can b 5. [Tenant Deprovisioning Provider](#5-tenant-deprovisioning-provider) 6. [Tenant Provisioning Success Handler](#6-tenant-provisioning-success-provider) 7. [Tenant Provisioning Failure Handler](#7-tenant-provisioning-failure-provider) +8. [Tenant Deployment Handler](#8-tenant-deployment-handler) Here's the invocation flow for quick understanding on how and when above artifacts are called, more details are provided in their own sections: @@ -135,6 +136,7 @@ import { TenantProvisioningFailureHandler, TenantProvisioningHandler, TenantProvisioningSuccessHandler, + TenantDeploymentHandler, } from '@arc-saas/orchestrator-service'; export interface AWSEventBridgeInterface { @@ -160,6 +162,8 @@ export class OrchestratorService implements OrchestratorServiceInterface { private handleTenantProvisioningSuccess: TenantProvisioningSuccessHandler, @inject(OrchestratorServiceBindings.TENANT_PROVISIONING_FAILURE_HANDLER) private handleTenantProvisioningFailure: TenantProvisioningFailureHandler, + @inject(OrchestratorServiceBindings.TENANT_DEPLOYMENT_HANDLER) + private handleTenantDeployment: TenantDeploymentHandler, ) {} handleEvent( @@ -173,8 +177,10 @@ export class OrchestratorService implements OrchestratorServiceInterface { return this.handleTenantDeprovisioning(eventBody.detail); case EventTypes.TENANT_PROVISIONING_SUCCESS: return this.handleTenantProvisioningSuccess(eventBody.detail); - case EventTypes.TENANT_PROVISIONING_FAILED: + case EventTypes.TENANT_PROVISIONING_FAILURE: return this.handleTenantProvisioningFailure(eventBody.detail); + case DefaultEventTypes.TENANT_DEPLOYMENT: + return this.handleTenantDeployment(eventBody); default: throw new Error(`Unsupported event type: ${eventType}`); } @@ -519,6 +525,14 @@ For example, In this provider you can implement any cleanup or notification need The way of binding this provider is similar to other provider, just the binding key is `OrchestratorServiceBindings.TENANT_PROVISIONING_FAILURE_HANDLER`. +#### 8. Tenant Deployment Provider + +This provider is intended to be the handler of the tenant deployment, which means any work after the provisioning that is required to make the tenant's application up and running, should be implemented here. + +For example, this can be adding some initial users. Populating some seed data in the application service etc. + +The way of binding this provider is similar to other provider, just the binding key is `OrchestratorServiceBindings.TENANT_DEPLOYMENT_HANDLER`. + ## Deployment The @arc-saas/orchestrator-service can be deployed in various ways, including as a serverless application. Here's how you can set it up for serverless deployment, specifically for AWS Lambda. diff --git a/services/orchestrator-service/src/__tests__/unit/component.unit.ts b/services/orchestrator-service/src/__tests__/unit/component.unit.ts index 16a8886..94d0bd8 100644 --- a/services/orchestrator-service/src/__tests__/unit/component.unit.ts +++ b/services/orchestrator-service/src/__tests__/unit/component.unit.ts @@ -11,6 +11,7 @@ import { OrchestratorService, BuilderService, TierDetailsFn, + TenantDeploymentHandlerProvider, } from './../../'; import {OrchestratorServiceComponent} from '../../component'; import {Provider} from '@loopback/context'; @@ -85,6 +86,8 @@ describe('OrchestratorServiceComponent', () => { TenantProvisioningSuccessHandlerProvider, [OrchestratorServiceBindings.TENANT_PROVISIONING_FAILURE_HANDLER.key]: TenantProvisioningFailureHandlerProvider, + [OrchestratorServiceBindings.TENANT_DEPLOYMENT_HANDLER.key]: + TenantDeploymentHandlerProvider, }; for (const [key] of Object.entries(providerMap)) { diff --git a/services/orchestrator-service/src/__tests__/unit/orchestrator-service.unit.ts b/services/orchestrator-service/src/__tests__/unit/orchestrator-service.unit.ts index fcd6bab..8fef3b1 100644 --- a/services/orchestrator-service/src/__tests__/unit/orchestrator-service.unit.ts +++ b/services/orchestrator-service/src/__tests__/unit/orchestrator-service.unit.ts @@ -6,6 +6,7 @@ import { TenantDeprovisioningHandler, TenantProvisioningSuccessHandler, TenantProvisioningFailureHandler, + TenantDeploymentHandler, } from '../..'; describe('OrchestratorService', () => { @@ -14,6 +15,7 @@ describe('OrchestratorService', () => { let tenantDeprovisioningHandlerStub: sinon.SinonStub; let tenantProvisioningSuccessHandlerStub: sinon.SinonStub; let tenantProvisioningFailureHandlerStub: sinon.SinonStub; + let tenantDeploymentHandlerStub: sinon.SinonStub; beforeEach(givenOrchestratorService); @@ -50,10 +52,10 @@ describe('OrchestratorService', () => { ).to.be.true(); }); - it('handles TENANT_PROVISIONING_FAILED event', async () => { + it('handles TENANT_PROVISIONING_FAILURE event', async () => { const eventBody = {tenantId: '123', error: 'Some error'}; await orchestratorService.handleEvent( - DefaultEventTypes.TENANT_PROVISIONING_FAILED, + DefaultEventTypes.TENANT_PROVISIONING_FAILURE, eventBody, ); expect( @@ -61,6 +63,18 @@ describe('OrchestratorService', () => { ).to.be.true(); }); + it('handles TENANT_DEPLOYMENT event', async () => { + const eventBody = { + tenantId: '123', + plan: {features: [{key: 'FEAT', value: 'FOO'}]}, + }; + await orchestratorService.handleEvent( + DefaultEventTypes.TENANT_DEPLOYMENT, + eventBody, + ); + expect(tenantDeploymentHandlerStub.calledOnceWith(eventBody)).to.be.true(); + }); + it('throws error for unsupported event type', async () => { const eventBody = {}; await expect( @@ -76,12 +90,14 @@ describe('OrchestratorService', () => { tenantDeprovisioningHandlerStub = sinon.stub(); tenantProvisioningSuccessHandlerStub = sinon.stub(); tenantProvisioningFailureHandlerStub = sinon.stub(); + tenantDeploymentHandlerStub = sinon.stub(); orchestratorService = new OrchestratorService( tenantProvisioningHandlerStub as unknown as TenantProvisioningHandler, tenantDeprovisioningHandlerStub as unknown as TenantDeprovisioningHandler, tenantProvisioningSuccessHandlerStub as unknown as TenantProvisioningSuccessHandler, tenantProvisioningFailureHandlerStub as unknown as TenantProvisioningFailureHandler, + tenantDeploymentHandlerStub as unknown as TenantDeploymentHandler, ); } }); diff --git a/services/orchestrator-service/src/component.ts b/services/orchestrator-service/src/component.ts index a88733a..f2e9a8e 100644 --- a/services/orchestrator-service/src/component.ts +++ b/services/orchestrator-service/src/component.ts @@ -19,6 +19,7 @@ import { TierDetailsProvider, TenantProvisioningSuccessHandlerProvider, TenantDeprovisioningHandlerProvider, + TenantDeploymentHandlerProvider, } from './services'; import {EventController} from './controllers'; import {RestApplication} from '@loopback/rest'; @@ -52,6 +53,8 @@ export class OrchestratorServiceComponent implements Component { TenantProvisioningSuccessHandlerProvider, [OrchestratorServiceBindings.TENANT_PROVISIONING_FAILURE_HANDLER.key]: TenantProvisioningFailureHandlerProvider, + [OrchestratorServiceBindings.TENANT_DEPLOYMENT_HANDLER.key]: + TenantDeploymentHandlerProvider, }); // Bind Service Classes if not provided by consumer of the component diff --git a/services/orchestrator-service/src/services/index.ts b/services/orchestrator-service/src/services/index.ts index d5790ba..b8ad43e 100644 --- a/services/orchestrator-service/src/services/index.ts +++ b/services/orchestrator-service/src/services/index.ts @@ -3,6 +3,7 @@ export * from './tenant-provisioning-handler.service'; export * from './tenant-provisioning-success-handler.service'; export * from './tenant-provisioning-failure-handler.service'; export * from './tenant-deprovisioning-handler.service'; +export * from './tenant-deployment-handler.service'; export * from './tier-details.service'; export * from './orchestrator.service'; export * from './types'; diff --git a/services/orchestrator-service/src/services/orchestrator.service.ts b/services/orchestrator-service/src/services/orchestrator.service.ts index 435d120..5583565 100644 --- a/services/orchestrator-service/src/services/orchestrator.service.ts +++ b/services/orchestrator-service/src/services/orchestrator.service.ts @@ -4,11 +4,14 @@ import { OrchestratorServiceBindings, OrchestratorServiceInterface, } from './types'; -import {TenantProvisioningHandler} from './tenant-provisioning-handler.service'; import {AnyObject} from '@loopback/repository'; -import {TenantDeprovisioningHandler} from './tenant-deprovisioning-handler.service'; -import {TenantProvisioningSuccessHandler} from './tenant-provisioning-success-handler.service'; -import {TenantProvisioningFailureHandler} from './tenant-provisioning-failure-handler.service'; +import { + TenantProvisioningHandler, + TenantDeprovisioningHandler, + TenantProvisioningSuccessHandler, + TenantProvisioningFailureHandler, + TenantDeploymentHandler, +} from './'; @injectable({scope: BindingScope.TRANSIENT}) export class OrchestratorService implements OrchestratorServiceInterface { @@ -21,6 +24,8 @@ export class OrchestratorService implements OrchestratorServiceInterface { private handleTenantProvisioningSuccess: TenantProvisioningSuccessHandler, @inject(OrchestratorServiceBindings.TENANT_PROVISIONING_FAILURE_HANDLER) private handleTenantProvisioningFailure: TenantProvisioningFailureHandler, + @inject(OrchestratorServiceBindings.TENANT_DEPLOYMENT_HANDLER) + private handleTenantDeployment: TenantDeploymentHandler, ) {} async handleEvent( @@ -34,8 +39,10 @@ export class OrchestratorService implements OrchestratorServiceInterface { return this.handleTenantDeprovisioning(eventBody); case DefaultEventTypes.TENANT_PROVISIONING_SUCCESS: return this.handleTenantProvisioningSuccess(eventBody); - case DefaultEventTypes.TENANT_PROVISIONING_FAILED: + case DefaultEventTypes.TENANT_PROVISIONING_FAILURE: return this.handleTenantProvisioningFailure(eventBody); + case DefaultEventTypes.TENANT_DEPLOYMENT: + return this.handleTenantDeployment(eventBody); default: throw new Error(`Unsupported event type: ${eventType}`); } diff --git a/services/orchestrator-service/src/services/tenant-deployment-handler.service.ts b/services/orchestrator-service/src/services/tenant-deployment-handler.service.ts new file mode 100644 index 0000000..428995c --- /dev/null +++ b/services/orchestrator-service/src/services/tenant-deployment-handler.service.ts @@ -0,0 +1,23 @@ +import {injectable, BindingScope, Provider} from '@loopback/core'; +import {AnyObject} from '@loopback/repository'; + +export type TenantDeploymentHandler = ( + body: T, +) => Promise; + +@injectable({scope: BindingScope.TRANSIENT}) +export class TenantDeploymentHandlerProvider + implements Provider +{ + constructor() {} + + value() { + return async (body: AnyObject) => this.handler(body); + } + + private async handler(body: AnyObject): Promise { + throw Error( + `${TenantDeploymentHandlerProvider.name} is not implemented. Follow the README for more details.`, + ); + } +} diff --git a/services/orchestrator-service/src/services/types.ts b/services/orchestrator-service/src/services/types.ts index 6fc3b41..caf7ada 100644 --- a/services/orchestrator-service/src/services/types.ts +++ b/services/orchestrator-service/src/services/types.ts @@ -5,6 +5,7 @@ import {TenantDeprovisioningHandler} from './tenant-deprovisioning-handler.servi import {AnyObject} from '@loopback/repository'; import {TenantProvisioningSuccessHandler} from './tenant-provisioning-success-handler.service'; import {TenantProvisioningFailureHandler} from './tenant-provisioning-failure-handler.service'; +import {TenantDeploymentHandler} from './tenant-deployment-handler.service'; const BINDING_PREFIX = `arc-saas`; @@ -26,7 +27,11 @@ export namespace OrchestratorServiceBindings { ); export const TENANT_PROVISIONING_FAILURE_HANDLER = BindingKey.create( - `${BINDING_PREFIX}.providers.tenant-provisioning-success-handler`, + `${BINDING_PREFIX}.providers.tenant-provisioning-failure-handler`, + ); + export const TENANT_DEPLOYMENT_HANDLER = + BindingKey.create( + `${BINDING_PREFIX}.providers.tenant-deployment-handler`, ); export const BUILDER_SERVICE = BindingKey.create( `${BINDING_PREFIX}.services.builder-service`, @@ -52,5 +57,9 @@ export enum DefaultEventTypes { TENANT_PROVISIONING = 'TENANT_PROVISIONING', TENANT_DEPROVISIONING = 'TENANT_DEPROVISIONING', TENANT_PROVISIONING_SUCCESS = 'TENANT_PROVISIONING_SUCCESS', - TENANT_PROVISIONING_FAILED = 'TENANT_PROVISIONING_FAILED', + TENANT_PROVISIONING_FAILURE = 'TENANT_PROVISIONING_FAILURE', + + TENANT_DEPLOYMENT = 'TENANT_DEPLOYMENT', + TENANT_DEPLOYMENT_SUCCESS = 'TENANT_DEPLOYMENT_SUCCESS', + TENANT_DEPLOYMENT_FAILURE = 'TENANT_DEPLOYMENT_FAILURE', } diff --git a/services/subscription-service/migrations/pg/migrations/20240805112128-remove-plan-items.js b/services/subscription-service/migrations/pg/migrations/20240805112128-remove-plan-items.js new file mode 100644 index 0000000..96581f3 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/20240805112128-remove-plan-items.js @@ -0,0 +1,59 @@ +'use strict'; + +var dbm; +var type; +var seed; +var fs = require('fs'); +var path = require('path'); +var Promise; + +/** + * We receive the dbmigrate dependency from dbmigrate initially. + * This enables us to not have to rely on NODE_PATH. + */ +exports.setup = function (options, seedLink) { + dbm = options.dbmigrate; + type = dbm.dataType; + seed = seedLink; + Promise = options.Promise; +}; + +exports.up = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112128-remove-plan-items-up.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports.down = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112128-remove-plan-items-down.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports._meta = { + version: 1, +}; diff --git a/services/subscription-service/migrations/pg/migrations/20240805112316-add-plan-sizes-table.js b/services/subscription-service/migrations/pg/migrations/20240805112316-add-plan-sizes-table.js new file mode 100644 index 0000000..c9be0cc --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/20240805112316-add-plan-sizes-table.js @@ -0,0 +1,59 @@ +'use strict'; + +var dbm; +var type; +var seed; +var fs = require('fs'); +var path = require('path'); +var Promise; + +/** + * We receive the dbmigrate dependency from dbmigrate initially. + * This enables us to not have to rely on NODE_PATH. + */ +exports.setup = function (options, seedLink) { + dbm = options.dbmigrate; + type = dbm.dataType; + seed = seedLink; + Promise = options.Promise; +}; + +exports.up = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112316-add-plan-sizes-table-up.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports.down = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112316-add-plan-sizes-table-down.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports._meta = { + version: 1, +}; diff --git a/services/subscription-service/migrations/pg/migrations/20240805112817-add-plan-size-column.js b/services/subscription-service/migrations/pg/migrations/20240805112817-add-plan-size-column.js new file mode 100644 index 0000000..7de5b51 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/20240805112817-add-plan-size-column.js @@ -0,0 +1,59 @@ +'use strict'; + +var dbm; +var type; +var seed; +var fs = require('fs'); +var path = require('path'); +var Promise; + +/** + * We receive the dbmigrate dependency from dbmigrate initially. + * This enables us to not have to rely on NODE_PATH. + */ +exports.setup = function (options, seedLink) { + dbm = options.dbmigrate; + type = dbm.dataType; + seed = seedLink; + Promise = options.Promise; +}; + +exports.up = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112817-add-plan-size-column-up.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports.down = function (db) { + var filePath = path.join( + __dirname, + 'sqls', + '20240805112817-add-plan-size-column-down.sql', + ); + return new Promise(function (resolve, reject) { + fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) { + if (err) return reject(err); + console.log('received data: ' + data); + + resolve(data); + }); + }).then(function (data) { + return db.runSql(data); + }); +}; + +exports._meta = { + version: 1, +}; diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240208115049-add-tier-column-to-plans-up.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240208115049-add-tier-column-to-plans-up.sql index 085f7c4..137b87a 100644 --- a/services/subscription-service/migrations/pg/migrations/sqls/20240208115049-add-tier-column-to-plans-up.sql +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240208115049-add-tier-column-to-plans-up.sql @@ -1,2 +1,2 @@ -- add tier column to plans table -ALTER TABLE main.plans ADD COLUMN tier smallint DEFAULT 0 NOT NULL ; \ No newline at end of file +ALTER TABLE main.plans ADD COLUMN tier text NOT NULL; \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240209122448-seed-data-up.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240209122448-seed-data-up.sql index c58d713..c63126f 100644 --- a/services/subscription-service/migrations/pg/migrations/sqls/20240209122448-seed-data-up.sql +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240209122448-seed-data-up.sql @@ -10,7 +10,7 @@ INSERT INTO main."plans"("name", created_on, created_by, description, price, cur FROM main.billing_cycles bb WHERE - cycle_name = 'MONTHLY'), 0); + cycle_name = 'MONTHLY'), "STANDARD"); INSERT INTO main."plans"("name", created_on, created_by, description, price, currency_id, meta_data, billing_cycle_id, tier) VALUES ('Premium', CURRENT_TIMESTAMP, '123e4567-e89b-12d3-a456-426614174002', 'Premium plan', 150,( @@ -24,7 +24,7 @@ INSERT INTO main."plans"("name", created_on, created_by, description, price, cur FROM main.billing_cycles bb WHERE - cycle_name = 'MONTHLY'), 1); + cycle_name = 'MONTHLY'), "PREMIUM"); INSERT INTO main.plan_items(created_on, created_by, "name", plan_item_type, plan_id, value) VALUES (CURRENT_TIMESTAMP, '123e4567-e89b-12d3-a456-426614174002', 'Database', 'database',( diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-down.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-down.sql new file mode 100644 index 0000000..5ba84f3 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-down.sql @@ -0,0 +1,16 @@ +CREATE TABLE plan_items ( + id uuid DEFAULT (md5(((random())::text || (clock_timestamp())::text)))::uuid NOT NULL , + created_on timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL , + modified_on timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL , + deleted boolean DEFAULT false NOT NULL , + deleted_on timestamptz , + deleted_by uuid , + created_by uuid NOT NULL , + modified_by uuid , + name varchar(100) NOT NULL , + plan_item_type varchar(30) NOT NULL , + plan_id uuid NOT NULL , + value jsonb NOT NULL, + CONSTRAINT pk_plan_items_id PRIMARY KEY ( id ), + CONSTRAINT fk_plan_items_plans FOREIGN KEY ( plan_id ) REFERENCES plans( id ) +); \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-up.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-up.sql new file mode 100644 index 0000000..355fbb7 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112128-remove-plan-items-up.sql @@ -0,0 +1 @@ +DROP TABLE main.plan_items; \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-down.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-down.sql new file mode 100644 index 0000000..5dd741c --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-down.sql @@ -0,0 +1 @@ +DROP TABLE main.plan_sizes; \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-up.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-up.sql new file mode 100644 index 0000000..e755e8f --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112316-add-plan-sizes-table-up.sql @@ -0,0 +1,15 @@ +CREATE TABLE main.plan_sizes +( + id uuid DEFAULT (md5(((random())::text || (clock_timestamp())::text)))::uuid NOT NULL , + size text NOT NULL, + config jsonb, + PRIMARY KEY (id), + created_on timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + modified_on timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + deleted boolean DEFAULT false NOT NULL, + deleted_on timestamptz, + deleted_by uuid, + created_by uuid NOT NULL, + modified_by uuid, + CONSTRAINT unique_size_name UNIQUE (size) +); \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-down.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-down.sql new file mode 100644 index 0000000..cad66c0 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-down.sql @@ -0,0 +1 @@ +ALTER TABLE IF EXISTS main.plans DROP COLUMN IF EXISTS size; \ No newline at end of file diff --git a/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-up.sql b/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-up.sql new file mode 100644 index 0000000..3e64cf9 --- /dev/null +++ b/services/subscription-service/migrations/pg/migrations/sqls/20240805112817-add-plan-size-column-up.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS main.plans + ADD COLUMN size text; \ No newline at end of file diff --git a/services/subscription-service/src/__tests__/acceptance/mock-data.ts b/services/subscription-service/src/__tests__/acceptance/mock-data.ts index 73259ad..ed5d06b 100644 --- a/services/subscription-service/src/__tests__/acceptance/mock-data.ts +++ b/services/subscription-service/src/__tests__/acceptance/mock-data.ts @@ -1,6 +1,6 @@ import {DataObject} from '@loopback/repository'; -import {PlanTier, SubscriptionStatus} from '../../enums'; -import {Plan, PlanItem, Resource, Service, Subscription} from '../../models'; +import {SubscriptionStatus} from '../../enums'; +import {Plan, Resource, Service, Subscription} from '../../models'; export const mockService: DataObject = { name: 'test-service', @@ -31,15 +31,7 @@ export const mockPlan: DataObject = { price: 100, currencyId: 'currrency-id', billingCycleId: 'test-billing-id', - tier: PlanTier.POOLED, -}; - -export const mockPlanItem: DataObject = { - name: 'test-plan-item', - planItemType: 'test-type', - value: { - test: 'test', - }, + tier: 'Standard', }; export const mockSubscription: DataObject = { diff --git a/services/subscription-service/src/__tests__/acceptance/plan-item.controller.acceptance.ts b/services/subscription-service/src/__tests__/acceptance/plan-item.controller.acceptance.ts deleted file mode 100644 index 5bf8df7..0000000 --- a/services/subscription-service/src/__tests__/acceptance/plan-item.controller.acceptance.ts +++ /dev/null @@ -1,143 +0,0 @@ -import {mockPlanItem} from './mock-data'; -import {Client, expect} from '@loopback/testlab'; -import {SubscriptionServiceApplication} from '../..'; -import {PlanItem} from '../../models'; -import {PermissionKey} from '../../permissions'; -import {PlanItemRepository} from '../../repositories'; - -import {getRepo, getToken, setupApplication} from './test-helper'; -import {STATUS_CODE} from '@sourceloop/core'; - -const basePath = '/plan-items'; - -describe('PlanItemController', () => { - let app: SubscriptionServiceApplication; - let client: Client; - - let savedPlanItem: PlanItem; - let planItemRepo: PlanItemRepository; - const updatedName = 'updated-test'; - before('setupApplication', async () => { - ({app, client} = await setupApplication()); - planItemRepo = await getRepo(app, 'repositories.PlanItemRepository'); - }); - - after(async () => { - await app.stop(); - }); - - beforeEach(async () => { - await seedData(); - }); - - afterEach(async () => { - await planItemRepo.deleteAllHard(); - }); - - it('invokes POST /plan-items with valid token', async () => { - const token = getToken([PermissionKey.CreatePlanItem]); - const {body} = await client - .post(basePath) - .set('Authorization', token) - .send({...mockPlanItem, name: 'test2'}) - .expect(STATUS_CODE.OK); - expect(body.id).to.be.String(); - expect(body.name).to.eql('test2'); - }); - - it('invokes GET /plan-items with valid token', async () => { - const token = getToken([PermissionKey.ViewPlanItem]); - const {body} = await client - .get(basePath) - .set('Authorization', token) - .expect(STATUS_CODE.OK); - expect(body.length).to.eql(1); - expect(body[0].name).to.eql(mockPlanItem.name); - }); - - it('should not allow GET /plan-items with invalid token', async () => { - const token = getToken([PermissionKey.ViewSubscription]); - await client - .get(basePath) - .set('Authorization', token) - .expect(STATUS_CODE.FORBIDDEN); - }); - - it('invokes GET /plan-items/{id} with valid token', async () => { - const token = getToken([PermissionKey.ViewPlanItem]); - const {body} = await client - .get(`${basePath}/${savedPlanItem.id}`) - .set('Authorization', token) - .expect(STATUS_CODE.OK); - expect(body.name).to.eql(mockPlanItem.name); - }); - - it('invokes GET /plan-items/count with valid token', async () => { - const token = getToken([PermissionKey.ViewPlanItem]); - const {body} = await client - .get(`${basePath}/count`) - .set('Authorization', token) - .expect(STATUS_CODE.OK); - expect(body.count).to.eql(1); - }); - - it('invokes PUT /plan-items/{id} with valid token', async () => { - const token = getToken([PermissionKey.UpdatePlanItem]); - - await client - .put(`${basePath}/${savedPlanItem.id}`) - .set('Authorization', token) - .send({...savedPlanItem, name: updatedName, id: undefined}) - .expect(STATUS_CODE.NO_CONTENT); - - const updated = await planItemRepo.findById(savedPlanItem.id); - expect(updated?.name).to.eql(updatedName); - }); - - it('invokes PATCH /plan-items/{id} with valid token', async () => { - const token = getToken([PermissionKey.UpdatePlanItem]); - - await client - .patch(`${basePath}/${savedPlanItem.id}`) - .set('Authorization', token) - .send({name: updatedName}) - .expect(STATUS_CODE.NO_CONTENT); - - const updated = await planItemRepo.findById(savedPlanItem.id); - expect(updated?.name).to.eql(updatedName); - }); - - it('invokes PATCH /plan-items with valid token', async () => { - const token = getToken([PermissionKey.UpdatePlanItem]); - - const {body} = await client - .patch(`${basePath}`) - .set('Authorization', token) - .send({name: 'updated-test-all'}) - .expect(STATUS_CODE.OK); - - expect(body.count).to.eql(1); - const updated = await planItemRepo.findById(savedPlanItem.id); - expect(updated?.name).to.eql('updated-test-all'); - }); - - it('invokes DELETE /plan-items/{id} with valid token', async () => { - const token = getToken([PermissionKey.DeletePlanItem]); - - await client - .delete(`${basePath}/${savedPlanItem.id}`) - .set('Authorization', token) - .expect(STATUS_CODE.NO_CONTENT); - - try { - await planItemRepo.findById(savedPlanItem.id); - throw new Error('Plan not deleted'); - } catch (err) { - expect(err.status).to.eql(STATUS_CODE.NOT_FOUND); - } - }); - - async function seedData() { - savedPlanItem = await planItemRepo.create(mockPlanItem); - } -}); diff --git a/services/subscription-service/src/component.ts b/services/subscription-service/src/component.ts index b2902c9..9455848 100644 --- a/services/subscription-service/src/component.ts +++ b/services/subscription-service/src/component.ts @@ -32,8 +32,8 @@ import {ISubscriptionServiceConfig} from './types'; import { BillingCycleRepository, CurrencyRepository, - PlanItemRepository, PlanRepository, + PlanSizesRepository, ResourceRepository, ServiceRepository, SubscriptionRepository, @@ -44,7 +44,8 @@ import { HomePageController, PingController, PlanController, - PlanItemController, + PlanFeaturesController, + PlanSizesController, PlanSubscriptionController, ResourceController, ServiceController, @@ -53,8 +54,8 @@ import { import { BillingCycle, Currency, - PlanItem, Plan, + PlanSizes, Resource, Service, Subscription, @@ -85,7 +86,7 @@ export class SubscriptionServiceComponent implements Component { this.application.api({ openapi: '3.0.0', info: { - title: 'Audit Service', + title: 'Subscription Service', version: '1.0.0', }, paths: {}, @@ -103,21 +104,21 @@ export class SubscriptionServiceComponent implements Component { this.repositories = [ BillingCycleRepository, CurrencyRepository, - PlanItemRepository, PlanRepository, ResourceRepository, ServiceRepository, SubscriptionRepository, + PlanSizesRepository, ]; this.models = [ BillingCycle, Currency, - PlanItem, Plan, Resource, Service, Subscription, + PlanSizes, ]; this.controllers = [ @@ -125,12 +126,13 @@ export class SubscriptionServiceComponent implements Component { HomePageController, PingController, CurrencyController, - PlanItemController, PlanController, ResourceController, ServiceController, SubscriptionController, PlanSubscriptionController, + PlanSizesController, + PlanFeaturesController, ]; } diff --git a/services/subscription-service/src/controllers/index.ts b/services/subscription-service/src/controllers/index.ts index 2a24d93..7910a50 100644 --- a/services/subscription-service/src/controllers/index.ts +++ b/services/subscription-service/src/controllers/index.ts @@ -2,9 +2,10 @@ export * from './ping.controller'; export * from './home-page.controller'; export * from './subscription.controller'; export * from './plan.controller'; -export * from './plan-item.controller'; export * from './service.controller'; export * from './resource.controller'; export * from './billing-cycle.controller'; export * from './currency.controller'; export * from './plan-subscription.controller'; +export * from './plan-sizes.controller'; +export * from './plan-features.controller'; diff --git a/services/subscription-service/src/controllers/plan-features.controller.ts b/services/subscription-service/src/controllers/plan-features.controller.ts new file mode 100644 index 0000000..fd0f294 --- /dev/null +++ b/services/subscription-service/src/controllers/plan-features.controller.ts @@ -0,0 +1,215 @@ +import {authorize} from 'loopback4-authorization'; +import {PermissionKey} from '../permissions'; +import {authenticate, STRATEGY} from 'loopback4-authentication'; +import { + param, + get, + getModelSchemaRef, + post, + requestBody, + patch, +} from '@loopback/rest'; +import {OPERATION_SECURITY_SPEC, STATUS_CODE} from '@sourceloop/core'; +import {Plan} from '../models'; +import { + Feature, + FeatureRepository, + FeatureValues, + FeatureValuesRepository, +} from '@sourceloop/feature-toggle-service'; +import {DataObject, repository} from '@loopback/repository'; +import {PlanRepository} from '../repositories'; + +const basePath = 'plans/{id}/features'; + +export class PlanFeaturesController { + constructor( + @repository(PlanRepository) + public planRepository: PlanRepository, + @repository(FeatureValuesRepository) + public featureValuesRepository: FeatureValuesRepository, + @repository(FeatureRepository) + public featureRepository: FeatureRepository, + ) {} + + @authorize({ + permissions: [PermissionKey.ViewPlanFeatures], + }) + @authenticate(STRATEGY.BEARER, { + passReqToCallback: true, + }) + @get(basePath, { + security: OPERATION_SECURITY_SPEC, + responses: { + [STATUS_CODE.OK]: { + description: 'Plan Features Retrieved', + content: { + 'application/json': { + schema: { + ...getModelSchemaRef(Plan), + ...getModelSchemaRef(FeatureValues), + }, + }, + }, + }, + }, + }) + async getPlanFeatures(@param.path.string('id') id: string): Promise< + DataObject & { + features: DataObject[]; + } + > { + const plan = await this.planRepository.findById(id, { + fields: ['id', 'name', 'tier', 'size'], + }); + const allFeatures = await this.featureRepository.find({ + fields: [ + 'id', + 'key', + 'name', + 'description', + 'type', + 'defaultValue', + 'metadata', + ], + }); + + const features: DataObject[] = []; + + const featureValuesThePlanHas = await this.featureValuesRepository.find({ + where: { + strategyEntityId: id, + }, + fields: [ + 'id', + 'featureKey', + 'value', + 'status', + 'strategyEntityId', + 'strategyKey', + ], + }); + + for (const featDefinition of allFeatures) { + features.push({ + ...featDefinition, + value: featureValuesThePlanHas.find( + e => e.featureKey === featDefinition.id, + ), + }); + } + + return { + ...plan, + features: features, + }; + } + + @authorize({ + permissions: [PermissionKey.AddPlanFeatures], + }) + @authenticate(STRATEGY.BEARER, { + passReqToCallback: true, + }) + @post(basePath, { + security: OPERATION_SECURITY_SPEC, + responses: { + [STATUS_CODE.OK]: { + description: 'Plan Features Created', + content: { + 'application/json': { + schema: { + ...getModelSchemaRef(FeatureValues), + }, + }, + }, + }, + }, + }) + async setPlanFeatures( + @param.path.string('id') id: string, + @requestBody() + featureValues: FeatureValues[], + ): Promise { + const values = featureValues.map(e => { + e.strategyEntityId = id; + e.strategyKey = 'Plan'; + return e; + }); + return this.featureValuesRepository.createAll(values); + } + + @authorize({ + permissions: [PermissionKey.UpdatePlanFeatures], + }) + @authenticate(STRATEGY.BEARER, { + passReqToCallback: true, + }) + @patch(basePath, { + security: OPERATION_SECURITY_SPEC, + responses: { + [STATUS_CODE.OK]: { + description: 'Plan Features Updated', + content: { + 'application/json': { + schema: { + type: 'array', + items: getModelSchemaRef(FeatureValues), + }, + }, + }, + }, + }, + }) + async updatePlanFeatures( + @param.path.string('id') id: string, + @requestBody({ + content: { + 'application/json': { + schema: { + type: 'array', + items: getModelSchemaRef(FeatureValues, {partial: true}), + }, + }, + }, + }) + featureValues: Partial[], + ): Promise { + const updatedFeatures: FeatureValues[] = []; + + for (const featureValue of featureValues) { + if (!featureValue.id) { + throw new Error('Feature value ID is required for update'); + } + + // Ensure the feature value belongs to the specified plan + const existingFeatureValue = await this.featureValuesRepository.findOne({ + where: { + id: featureValue.id, + strategyEntityId: id, + strategyKey: 'Plan', + }, + }); + + if (!existingFeatureValue) { + throw new Error( + `Feature value with ID ${featureValue.id} not found for this plan`, + ); + } + + // Update the feature value + await this.featureValuesRepository.updateById( + featureValue.id, + featureValue, + ); + + // Fetch the updated feature value + const updatedFeatureValue = await this.featureValuesRepository.findById( + featureValue.id, + ); + updatedFeatures.push(updatedFeatureValue); + } + + return updatedFeatures; + } +} diff --git a/services/subscription-service/src/controllers/plan-item.controller.ts b/services/subscription-service/src/controllers/plan-sizes.controller.ts similarity index 57% rename from services/subscription-service/src/controllers/plan-item.controller.ts rename to services/subscription-service/src/controllers/plan-sizes.controller.ts index 1a99731..c880999 100644 --- a/services/subscription-service/src/controllers/plan-item.controller.ts +++ b/services/subscription-service/src/controllers/plan-sizes.controller.ts @@ -16,22 +16,23 @@ import { del, requestBody, } from '@loopback/rest'; -import {PlanItem} from '../models'; -import {PlanItemRepository} from '../repositories'; +import {PlanSizes} from '../models'; +import {PlanSizesRepository} from '../repositories'; import {authorize} from 'loopback4-authorization'; -import {authenticate, STRATEGY} from 'loopback4-authentication'; import {PermissionKey} from '../permissions'; +import {authenticate, STRATEGY} from 'loopback4-authentication'; import {OPERATION_SECURITY_SPEC, STATUS_CODE} from '@sourceloop/core'; -const basePath = '/plan-items'; -export class PlanItemController { +const basePath = '/plan-sizes'; + +export class PlanSizesController { constructor( - @repository(PlanItemRepository) - public planItemRepository: PlanItemRepository, + @repository(PlanSizesRepository) + public planSizesRepository: PlanSizesRepository, ) {} @authorize({ - permissions: [PermissionKey.CreatePlanItem], + permissions: [PermissionKey.CreatePlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -40,10 +41,8 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { - description: 'PlanItem model instance', - content: { - 'application/json': {schema: getModelSchemaRef(PlanItem)}, - }, + description: 'PlanSizes model instance', + content: {'application/json': {schema: getModelSchemaRef(PlanSizes)}}, }, }, }) @@ -51,20 +50,20 @@ export class PlanItemController { @requestBody({ content: { 'application/json': { - schema: getModelSchemaRef(PlanItem, { - title: 'NewPlanItem', + schema: getModelSchemaRef(PlanSizes, { + title: 'NewPlanSizes', exclude: ['id'], }), }, }, }) - planItem: Omit, - ): Promise { - return this.planItemRepository.create(planItem); + planSizes: Omit, + ): Promise { + return this.planSizesRepository.create(planSizes); } @authorize({ - permissions: [PermissionKey.ViewPlanItem], + permissions: [PermissionKey.ViewPlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -73,17 +72,19 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { - description: 'PlanItem model count', + description: 'PlanSizes model count', content: {'application/json': {schema: CountSchema}}, }, }, }) - async count(@param.where(PlanItem) where?: Where): Promise { - return this.planItemRepository.count(where); + async count( + @param.where(PlanSizes) where?: Where, + ): Promise { + return this.planSizesRepository.count(where); } @authorize({ - permissions: [PermissionKey.ViewPlanItem], + permissions: [PermissionKey.ViewPlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -92,12 +93,12 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { - description: 'Array of PlanItem model instances', + description: 'Array of PlanSizes model instances', content: { 'application/json': { schema: { type: 'array', - items: getModelSchemaRef(PlanItem, {includeRelations: true}), + items: getModelSchemaRef(PlanSizes, {includeRelations: true}), }, }, }, @@ -105,13 +106,13 @@ export class PlanItemController { }, }) async find( - @param.filter(PlanItem) filter?: Filter, - ): Promise { - return this.planItemRepository.find(filter); + @param.filter(PlanSizes) filter?: Filter, + ): Promise { + return this.planSizesRepository.find(filter); } @authorize({ - permissions: [PermissionKey.UpdatePlanItem], + permissions: [PermissionKey.UpdatePlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -120,7 +121,7 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { - description: 'PlanItem PATCH success count', + description: 'PlanSizes PATCH success count', content: {'application/json': {schema: CountSchema}}, }, }, @@ -129,18 +130,18 @@ export class PlanItemController { @requestBody({ content: { 'application/json': { - schema: getModelSchemaRef(PlanItem, {partial: true}), + schema: getModelSchemaRef(PlanSizes, {partial: true}), }, }, }) - planItem: PlanItem, - @param.where(PlanItem) where?: Where, + planSizes: PlanSizes, + @param.where(PlanSizes) where?: Where, ): Promise { - return this.planItemRepository.updateAll(planItem, where); + return this.planSizesRepository.updateAll(planSizes, where); } @authorize({ - permissions: [PermissionKey.ViewPlanItem], + permissions: [PermissionKey.ViewPlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -149,10 +150,10 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { - description: 'PlanItem model instance', + description: 'PlanSizes model instance', content: { 'application/json': { - schema: getModelSchemaRef(PlanItem, {includeRelations: true}), + schema: getModelSchemaRef(PlanSizes, {includeRelations: true}), }, }, }, @@ -160,14 +161,14 @@ export class PlanItemController { }) async findById( @param.path.string('id') id: string, - @param.filter(PlanItem, {exclude: 'where'}) - filter?: FilterExcludingWhere, - ): Promise { - return this.planItemRepository.findById(id, filter); + @param.filter(PlanSizes, {exclude: 'where'}) + filter?: FilterExcludingWhere, + ): Promise { + return this.planSizesRepository.findById(id, filter); } @authorize({ - permissions: [PermissionKey.UpdatePlanItem], + permissions: [PermissionKey.UpdatePlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -176,7 +177,7 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { - description: 'PlanItem PATCH success', + description: 'PlanSizes PATCH success', }, }, }) @@ -185,17 +186,17 @@ export class PlanItemController { @requestBody({ content: { 'application/json': { - schema: getModelSchemaRef(PlanItem, {partial: true}), + schema: getModelSchemaRef(PlanSizes, {partial: true}), }, }, }) - planItem: PlanItem, + planSizes: PlanSizes, ): Promise { - await this.planItemRepository.updateById(id, planItem); + await this.planSizesRepository.updateById(id, planSizes); } @authorize({ - permissions: [PermissionKey.UpdatePlanItem], + permissions: [PermissionKey.UpdatePlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -204,19 +205,19 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { - description: 'PlanItem PUT success', + description: 'PlanSizes PUT success', }, }, }) async replaceById( @param.path.string('id') id: string, - @requestBody() planItem: PlanItem, + @requestBody() planSizes: PlanSizes, ): Promise { - await this.planItemRepository.replaceById(id, planItem); + await this.planSizesRepository.replaceById(id, planSizes); } @authorize({ - permissions: [PermissionKey.DeletePlanItem], + permissions: [PermissionKey.DeletePlanSizes], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, @@ -225,11 +226,11 @@ export class PlanItemController { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { - description: 'PlanItem DELETE success', + description: 'PlanSizes DELETE success', }, }, }) async deleteById(@param.path.string('id') id: string): Promise { - await this.planItemRepository.deleteById(id); + await this.planSizesRepository.deleteById(id); } } diff --git a/services/subscription-service/src/enums/index.ts b/services/subscription-service/src/enums/index.ts index 26539c7..f908ad7 100644 --- a/services/subscription-service/src/enums/index.ts +++ b/services/subscription-service/src/enums/index.ts @@ -1,3 +1,2 @@ export * from './billing-cycle.enum'; export * from './subscription-status.enum'; -export * from './plans-tier.enum'; diff --git a/services/subscription-service/src/enums/plans-tier.enum.ts b/services/subscription-service/src/enums/plans-tier.enum.ts deleted file mode 100644 index acc3154..0000000 --- a/services/subscription-service/src/enums/plans-tier.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum PlanTier { - POOLED, - SILO, -} diff --git a/services/subscription-service/src/models/index.ts b/services/subscription-service/src/models/index.ts index 1685546..0dc32c6 100644 --- a/services/subscription-service/src/models/index.ts +++ b/services/subscription-service/src/models/index.ts @@ -1,7 +1,7 @@ export * from './plan.model'; export * from './subscription.model'; -export * from './plan-item.model'; export * from './service.model'; export * from './resource.model'; export * from './billing-cycle.model'; export * from './currency.model'; +export * from './plan-sizes.model'; diff --git a/services/subscription-service/src/models/plan-item.model.ts b/services/subscription-service/src/models/plan-item.model.ts deleted file mode 100644 index 7fdec65..0000000 --- a/services/subscription-service/src/models/plan-item.model.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {belongsTo, model, property} from '@loopback/repository'; -import {UserModifiableEntity} from '@sourceloop/core'; -import {Plan} from './plan.model'; - -@model({ - name: 'plan_items', -}) -export class PlanItem extends UserModifiableEntity { - @property({ - type: 'string', - id: true, - generated: true, - }) - id: string; - - @property({ - type: 'string', - required: true, - description: 'name of the plan item', - }) - name: string; - - @property({ - type: 'string', - required: true, - name: 'plan_item_type', - description: 'type of the plan item', - }) - planItemType: string; - - @property({ - type: 'object', - required: true, - description: 'value of the plan item', - }) - value: object; - - @belongsTo(() => Plan, undefined, { - description: 'plan id of the plan item', - name: 'plan_id', - }) - planId: string; - - constructor(data?: Partial) { - super(data); - } -} - -export interface PlanItemRelations { - plan: Plan; -} - -export type PlanItemWithRelations = PlanItem & PlanItemRelations; diff --git a/services/subscription-service/src/models/plan-sizes.model.ts b/services/subscription-service/src/models/plan-sizes.model.ts new file mode 100644 index 0000000..77b7f81 --- /dev/null +++ b/services/subscription-service/src/models/plan-sizes.model.ts @@ -0,0 +1,33 @@ +import {model, property} from '@loopback/repository'; +import {UserModifiableEntity} from '@sourceloop/core'; + +@model({ + name: 'plan_sizes', +}) +export class PlanSizes extends UserModifiableEntity { + @property({ + type: 'string', + id: true, + generated: true, + }) + id: string; + + @property({ + type: 'string', + required: true, + }) + size: string; + + @property({ + type: 'object', + }) + config?: object; + + constructor(data?: Partial) { + super(data); + } +} + +export interface PlanSizesRelations {} + +export type PlanSizesWithRelations = PlanSizes; diff --git a/services/subscription-service/src/models/plan.model.ts b/services/subscription-service/src/models/plan.model.ts index 4d074c1..9002c06 100644 --- a/services/subscription-service/src/models/plan.model.ts +++ b/services/subscription-service/src/models/plan.model.ts @@ -1,10 +1,7 @@ -import {model, property, hasMany, belongsTo} from '@loopback/repository'; +import {model, property, belongsTo} from '@loopback/repository'; import {UserModifiableEntity} from '@sourceloop/core'; -import {PlanItem} from './plan-item.model'; import {BillingCycle} from './billing-cycle.model'; import {Currency} from './currency.model'; -import {numericEnumValues} from '../utils'; -import {PlanTier} from '../enums'; @model({ name: 'plans', @@ -31,29 +28,30 @@ export class Plan extends UserModifiableEntity { description?: string; @property({ - type: 'number', + type: 'string', required: true, - description: 'Tier of the plan, it can be - 0(Pooled) and 1(Silo)', - jsonSchema: { - enum: numericEnumValues(PlanTier), - }, - default: PlanTier.POOLED, + description: 'Tier of the plan.', }) - tier: PlanTier; + tier: string; + + @property({ + type: 'string', + description: 'Size of the plan.', + }) + size?: string; @property({ type: 'number', required: true, }) price: number; + @property({ type: 'object', name: 'meta_data', description: 'Meta data of the plan', }) metaData?: object; - @hasMany(() => PlanItem, {keyTo: 'planId'}) - planItems: PlanItem; @belongsTo( () => BillingCycle, @@ -76,8 +74,6 @@ export class Plan extends UserModifiableEntity { } } -export interface PlanRelations { - planItems: PlanItem[]; -} +export interface PlanRelations {} -export type PlanWithRelations = Plan & PlanRelations; +export type PlanWithRelations = Plan; diff --git a/services/subscription-service/src/openapi.json b/services/subscription-service/src/openapi.json index e7a74f8..8914c5e 100644 --- a/services/subscription-service/src/openapi.json +++ b/services/subscription-service/src/openapi.json @@ -1,9 +1,9 @@ { "openapi": "3.0.0", "info": { - "title": "subscription-service", + "title": "Subscription Service", "version": "1.0.0", - "description": "subscription-service", + "description": "Subscription management microservice for SaaS control plane", "contact": { "name": "Sourcefuse" } @@ -13,7 +13,9 @@ "get": { "x-controller-name": "BillinCycleController", "x-operation-name": "count", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -55,7 +57,9 @@ "put": { "x-controller-name": "BillinCycleController", "x-operation-name": "replaceById", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -92,7 +96,9 @@ "patch": { "x-controller-name": "BillinCycleController", "x-operation-name": "updateById", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -129,7 +135,9 @@ "get": { "x-controller-name": "BillinCycleController", "x-operation-name": "findById", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -174,7 +182,9 @@ "delete": { "x-controller-name": "BillinCycleController", "x-operation-name": "deleteById", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -203,7 +213,9 @@ "post": { "x-controller-name": "BillinCycleController", "x-operation-name": "create", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -236,7 +248,9 @@ "patch": { "x-controller-name": "BillinCycleController", "x-operation-name": "updateAll", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -285,7 +299,9 @@ "get": { "x-controller-name": "BillinCycleController", "x-operation-name": "find", - "tags": ["BillinCycleController"], + "tags": [ + "BillinCycleController" + ], "security": [ { "HTTPBearer": [] @@ -327,7 +343,9 @@ "get": { "x-controller-name": "CurrencyController", "x-operation-name": "count", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -369,7 +387,9 @@ "put": { "x-controller-name": "CurrencyController", "x-operation-name": "replaceById", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -406,7 +426,9 @@ "patch": { "x-controller-name": "CurrencyController", "x-operation-name": "updateById", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -443,7 +465,9 @@ "get": { "x-controller-name": "CurrencyController", "x-operation-name": "findById", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -488,7 +512,9 @@ "delete": { "x-controller-name": "CurrencyController", "x-operation-name": "deleteById", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -517,7 +543,9 @@ "post": { "x-controller-name": "CurrencyController", "x-operation-name": "create", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -550,7 +578,9 @@ "patch": { "x-controller-name": "CurrencyController", "x-operation-name": "updateAll", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -599,7 +629,9 @@ "get": { "x-controller-name": "CurrencyController", "x-operation-name": "find", - "tags": ["CurrencyController"], + "tags": [ + "CurrencyController" + ], "security": [ { "HTTPBearer": [] @@ -637,32 +669,13 @@ "operationId": "CurrencyController.find" } }, - "/ping": { - "get": { - "x-controller-name": "PingController", - "x-operation-name": "ping", - "tags": ["PingController"], - "responses": { - "200": { - "description": "Ping Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PingResponse" - } - } - } - } - }, - "description": "", - "operationId": "PingController.ping" - } - }, - "/plan-items/count": { + "/feature-values/count": { "get": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "count", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -670,7 +683,7 @@ ], "responses": { "200": { - "description": "PlanItem model count", + "description": "FeatureValues model count", "content": { "application/json": { "schema": { @@ -680,7 +693,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7012 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeatureValues |\n| 9 |\n", "parameters": [ { "name": "where", @@ -689,22 +702,24 @@ "application/json": { "schema": { "type": "object", - "title": "plan_items.WhereFilter", + "title": "feature_values.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } } ], - "operationId": "PlanItemController.count" + "operationId": "FeatureValuesController.count" } }, - "/plan-items/{id}": { + "/feature-values/{id}": { "put": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "replaceById", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -712,10 +727,10 @@ ], "responses": { "204": { - "description": "PlanItem PUT success" + "description": "FeatureValues PUT success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7010 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeatureValues |\n| 11 |\n", "parameters": [ { "name": "id", @@ -730,18 +745,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanItem" + "$ref": "#/components/schemas/FeatureValues" } } }, "x-parameter-index": 1 }, - "operationId": "PlanItemController.replaceById" + "operationId": "FeatureValuesController.replaceById" }, "patch": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "updateById", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -749,10 +766,10 @@ ], "responses": { "204": { - "description": "PlanItem PATCH success" + "description": "FeatureValues PATCH success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7010 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeatureValues |\n| 11 |\n", "parameters": [ { "name": "id", @@ -767,18 +784,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanItemPartial" + "$ref": "#/components/schemas/FeatureValuesPartial" } } }, "x-parameter-index": 1 }, - "operationId": "PlanItemController.updateById" + "operationId": "FeatureValuesController.updateById" }, "get": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "findById", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -786,17 +805,17 @@ ], "responses": { "200": { - "description": "PlanItem model instance", + "description": "FeatureValues model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanItemWithRelations" + "$ref": "#/components/schemas/FeatureValuesWithRelations" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7012 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeatureValues |\n| 9 |\n", "parameters": [ { "name": "id", @@ -812,18 +831,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/plan_items.Filter" + "$ref": "#/components/schemas/feature_values.Filter" } } } } ], - "operationId": "PlanItemController.findById" + "operationId": "FeatureValuesController.findById" }, "delete": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "deleteById", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -831,10 +852,10 @@ ], "responses": { "204": { - "description": "PlanItem DELETE success" + "description": "FeatureValues DELETE success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7011 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| DeleteFeatureValues |\n| 12 |\n", "parameters": [ { "name": "id", @@ -845,14 +866,16 @@ "required": true } ], - "operationId": "PlanItemController.deleteById" + "operationId": "FeatureValuesController.deleteById" } }, - "/plan-items": { + "/feature-values": { "post": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "create", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -860,32 +883,34 @@ ], "responses": { "200": { - "description": "PlanItem model instance", + "description": "FeatureValues model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanItem" + "$ref": "#/components/schemas/FeatureValues" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7009 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| CreateFeatureValues |\n| 10 |\n", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewPlanItem" + "$ref": "#/components/schemas/NewFeatureValues" } } } }, - "operationId": "PlanItemController.create" + "operationId": "FeatureValuesController.create" }, "patch": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "updateAll", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -893,7 +918,7 @@ ], "responses": { "200": { - "description": "PlanItem PATCH success count", + "description": "FeatureValues PATCH success count", "content": { "application/json": { "schema": { @@ -903,7 +928,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7010 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeatureValues |\n| 11 |\n", "parameters": [ { "name": "where", @@ -912,9 +937,9 @@ "application/json": { "schema": { "type": "object", - "title": "plan_items.WhereFilter", + "title": "feature_values.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } @@ -924,17 +949,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanItemPartial" + "$ref": "#/components/schemas/FeatureValuesPartial" } } } }, - "operationId": "PlanItemController.updateAll" + "operationId": "FeatureValuesController.updateAll" }, "get": { - "x-controller-name": "PlanItemController", + "x-controller-name": "FeatureValuesController", "x-operation-name": "find", - "tags": ["PlanItemController"], + "tags": [ + "FeatureValuesController" + ], "security": [ { "HTTPBearer": [] @@ -942,20 +969,20 @@ ], "responses": { "200": { - "description": "Array of PlanItem model instances", + "description": "Array of FeatureValues model instances", "content": { "application/json": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/PlanItemWithRelations" + "$ref": "#/components/schemas/FeatureValuesWithRelations" } } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7012 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeatureValues |\n| 9 |\n", "parameters": [ { "name": "filter", @@ -963,20 +990,22 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/plan_items.Filter1" + "$ref": "#/components/schemas/feature_values.Filter1" } } } } ], - "operationId": "PlanItemController.find" + "operationId": "FeatureValuesController.find" } }, - "/plans/count": { + "/features/count": { "get": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "count", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -984,7 +1013,7 @@ ], "responses": { "200": { - "description": "Plan model count", + "description": "Feature model count", "content": { "application/json": { "schema": { @@ -994,7 +1023,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeature |\n| 1 |\n", "parameters": [ { "name": "where", @@ -1003,22 +1032,24 @@ "application/json": { "schema": { "type": "object", - "title": "plans.WhereFilter", + "title": "features.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } } ], - "operationId": "PlanController.count" + "operationId": "FeatureController.count" } }, - "/plans/{id}": { + "/features/{id}": { "put": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "replaceById", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1026,10 +1057,10 @@ ], "responses": { "204": { - "description": "Plan PUT success" + "description": "Feature PUT success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeature |\n| 3 |\n", "parameters": [ { "name": "id", @@ -1044,18 +1075,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Plan" + "$ref": "#/components/schemas/Feature" } } }, "x-parameter-index": 1 }, - "operationId": "PlanController.replaceById" + "operationId": "FeatureController.replaceById" }, "patch": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "updateById", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1063,10 +1096,10 @@ ], "responses": { "204": { - "description": "Plan PATCH success" + "description": "Feature PATCH success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeature |\n| 3 |\n", "parameters": [ { "name": "id", @@ -1081,18 +1114,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanPartial" + "$ref": "#/components/schemas/FeaturePartial" } } }, "x-parameter-index": 1 }, - "operationId": "PlanController.updateById" + "operationId": "FeatureController.updateById" }, "get": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "findById", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1100,17 +1135,17 @@ ], "responses": { "200": { - "description": "Plan model instance", + "description": "Feature model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanWithRelations" + "$ref": "#/components/schemas/FeatureWithRelations" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeature |\n| 1 |\n", "parameters": [ { "name": "id", @@ -1126,18 +1161,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/plans.Filter" + "$ref": "#/components/schemas/features.Filter" } } } } ], - "operationId": "PlanController.findById" + "operationId": "FeatureController.findById" }, "delete": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "deleteById", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1145,10 +1182,10 @@ ], "responses": { "204": { - "description": "Plan DELETE success" + "description": "Feature DELETE success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7007 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| DeleteFeature |\n| 4 |\n", "parameters": [ { "name": "id", @@ -1159,14 +1196,16 @@ "required": true } ], - "operationId": "PlanController.deleteById" + "operationId": "FeatureController.deleteById" } }, - "/plans": { + "/features": { "post": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "create", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1174,32 +1213,34 @@ ], "responses": { "200": { - "description": "Plan model instance", + "description": "Feature model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Plan" + "$ref": "#/components/schemas/Feature" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7005 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| CreateFeature |\n| 2 |\n", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewPlan" + "$ref": "#/components/schemas/NewFeature" } } } }, - "operationId": "PlanController.create" + "operationId": "FeatureController.create" }, "patch": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "updateAll", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1207,7 +1248,7 @@ ], "responses": { "200": { - "description": "Plan PATCH success count", + "description": "Feature PATCH success count", "content": { "application/json": { "schema": { @@ -1217,7 +1258,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| UpdateFeature |\n| 3 |\n", "parameters": [ { "name": "where", @@ -1226,9 +1267,9 @@ "application/json": { "schema": { "type": "object", - "title": "plans.WhereFilter", + "title": "features.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } @@ -1238,17 +1279,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PlanPartial" + "$ref": "#/components/schemas/FeaturePartial" } } } }, - "operationId": "PlanController.updateAll" + "operationId": "FeatureController.updateAll" }, "get": { - "x-controller-name": "PlanController", + "x-controller-name": "FeatureController", "x-operation-name": "find", - "tags": ["PlanController"], + "tags": [ + "FeatureController" + ], "security": [ { "HTTPBearer": [] @@ -1256,20 +1299,20 @@ ], "responses": { "200": { - "description": "Array of Plan model instances", + "description": "Array of Feature model instances", "content": { "application/json": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/PlanWithRelations" + "$ref": "#/components/schemas/FeatureWithRelations" } } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| ViewFeature |\n| 1 |\n", "parameters": [ { "name": "filter", @@ -1277,28 +1320,48 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/plans.Filter1" + "$ref": "#/components/schemas/features.Filter1" } } } } ], - "operationId": "PlanController.find" + "operationId": "FeatureController.find" } }, - "/resources/count": { + "/ping": { "get": { - "x-controller-name": "ResourceController", - "x-operation-name": "count", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] + "x-controller-name": "PingController", + "x-operation-name": "ping", + "tags": [ + "PingController" + ], + "responses": { + "200": { + "description": "Ping Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PingResponse" + } + } + } } + }, + "description": "", + "operationId": "PingController.ping" + } + }, + "/plan-sizes/count": { + "get": { + "x-controller-name": "PlanSizesController", + "x-operation-name": "count", + "tags": [ + "PlanSizesController" ], "responses": { "200": { - "description": "Resource model count", + "description": "PlanSizes model count", "content": { "application/json": { "schema": { @@ -1308,7 +1371,6 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "where", @@ -1317,33 +1379,36 @@ "application/json": { "schema": { "type": "object", - "title": "resources.WhereFilter", + "title": "plan_sizes.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } } ], - "operationId": "ResourceController.count" + "operationId": "PlanSizesController.count" } }, - "/resources/{id}": { + "/plan-sizes/{id}": { "put": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "replaceById", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "204": { - "description": "Resource PUT success" + "description": "No Content", + "content": { + "application/json": { + "schema": { + "description": "PlanSizes PUT success" + } + } + } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "id", @@ -1358,29 +1423,32 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Resource" + "$ref": "#/components/schemas/PlanSizes" } } }, "x-parameter-index": 1 }, - "operationId": "ResourceController.replaceById" + "operationId": "PlanSizesController.replaceById" }, "patch": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "updateById", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "204": { - "description": "Resource PATCH success" + "description": "No Content", + "content": { + "application/json": { + "schema": { + "description": "PlanSizes PATCH success" + } + } + } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "id", @@ -1395,36 +1463,32 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResourcePartial" + "$ref": "#/components/schemas/PlanSizesPartial" } } }, "x-parameter-index": 1 }, - "operationId": "ResourceController.updateById" + "operationId": "PlanSizesController.updateById" }, "get": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "findById", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "200": { - "description": "Resource model instance", + "description": "PlanSizes model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResourceWithRelations" + "$ref": "#/components/schemas/PlanSizesWithRelations" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "id", @@ -1440,29 +1504,32 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/resources.Filter" + "$ref": "#/components/schemas/plan_sizes.Filter" } } } } ], - "operationId": "ResourceController.findById" + "operationId": "PlanSizesController.findById" }, "delete": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "deleteById", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "204": { - "description": "Resource DELETE success" + "description": "No Content", + "content": { + "application/json": { + "schema": { + "description": "PlanSizes DELETE success" + } + } + } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7015 |\n", "parameters": [ { "name": "id", @@ -1473,55 +1540,48 @@ "required": true } ], - "operationId": "ResourceController.deleteById" + "operationId": "PlanSizesController.deleteById" } }, - "/resources": { + "/plan-sizes": { "post": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "create", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "200": { - "description": "Resource model instance", + "description": "PlanSizes model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Resource" + "$ref": "#/components/schemas/PlanSizes" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7013 |\n", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewResource" + "$ref": "#/components/schemas/NewPlanSizes" } } } }, - "operationId": "ResourceController.create" + "operationId": "PlanSizesController.create" }, "patch": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "updateAll", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "200": { - "description": "Resource PATCH success count", + "description": "PlanSizes PATCH success count", "content": { "application/json": { "schema": { @@ -1531,7 +1591,6 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "where", @@ -1540,9 +1599,9 @@ "application/json": { "schema": { "type": "object", - "title": "resources.WhereFilter", + "title": "plan_sizes.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } @@ -1552,38 +1611,34 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResourcePartial" + "$ref": "#/components/schemas/PlanSizesPartial" } } } }, - "operationId": "ResourceController.updateAll" + "operationId": "PlanSizesController.updateAll" }, "get": { - "x-controller-name": "ResourceController", + "x-controller-name": "PlanSizesController", "x-operation-name": "find", - "tags": ["ResourceController"], - "security": [ - { - "HTTPBearer": [] - } + "tags": [ + "PlanSizesController" ], "responses": { "200": { - "description": "Array of Resource model instances", + "description": "Array of PlanSizes model instances", "content": { "application/json": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/ResourceWithRelations" + "$ref": "#/components/schemas/PlanSizesWithRelations" } } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "filter", @@ -1591,20 +1646,22 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/resources.Filter1" + "$ref": "#/components/schemas/plan_sizes.Filter1" } } } } ], - "operationId": "ResourceController.find" + "operationId": "PlanSizesController.find" } }, - "/services/count": { + "/plans/count": { "get": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "count", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1612,7 +1669,7 @@ ], "responses": { "200": { - "description": "Service model count", + "description": "Plan model count", "content": { "application/json": { "schema": { @@ -1622,7 +1679,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", "parameters": [ { "name": "where", @@ -1631,33 +1688,42 @@ "application/json": { "schema": { "type": "object", - "title": "services.WhereFilter", + "title": "plans.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } } ], - "operationId": "ServiceController.count" + "operationId": "PlanController.count" } }, - "/services/{id}": { - "put": { - "x-controller-name": "ServiceController", - "x-operation-name": "replaceById", - "tags": ["ServiceController"], + "/plans/{id}/subscriptions": { + "get": { + "x-controller-name": "PlanSubscriptionController", + "x-operation-name": "find", + "tags": [ + "PlanSubscriptionController" + ], "security": [ { "HTTPBearer": [] } ], "responses": { - "204": { - "description": "Service PUT success" + "200": { + "description": "Plan model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionWithRelations" + } + } + } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n| 7004 |\n", "parameters": [ { "name": "id", @@ -1668,22 +1734,55 @@ "required": true } ], - "requestBody": { - "content": { - "application/json": { + "operationId": "PlanSubscriptionController.find" + } + }, + "/plans/{id}": { + "put": { + "x-controller-name": "PlanController", + "x-operation-name": "replaceById", + "tags": [ + "PlanController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Plan PUT success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { "schema": { - "$ref": "#/components/schemas/Service" + "$ref": "#/components/schemas/Plan" } } }, "x-parameter-index": 1 }, - "operationId": "ServiceController.replaceById" + "operationId": "PlanController.replaceById" }, "patch": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "updateById", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1691,10 +1790,10 @@ ], "responses": { "204": { - "description": "Service PATCH success" + "description": "Plan PATCH success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", "parameters": [ { "name": "id", @@ -1709,18 +1808,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServicePartial" + "$ref": "#/components/schemas/PlanPartial" } } }, "x-parameter-index": 1 }, - "operationId": "ServiceController.updateById" + "operationId": "PlanController.updateById" }, "get": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "findById", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1728,17 +1829,17 @@ ], "responses": { "200": { - "description": "Service model instance", + "description": "Plan model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServiceWithRelations" + "$ref": "#/components/schemas/PlanWithRelations" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", "parameters": [ { "name": "id", @@ -1754,18 +1855,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/services.Filter" + "$ref": "#/components/schemas/plans.Filter" } } } } ], - "operationId": "ServiceController.findById" + "operationId": "PlanController.findById" }, "delete": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "deleteById", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1773,10 +1876,10 @@ ], "responses": { "204": { - "description": "Service DELETE success" + "description": "Plan DELETE success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7019 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7007 |\n", "parameters": [ { "name": "id", @@ -1787,14 +1890,16 @@ "required": true } ], - "operationId": "ServiceController.deleteById" + "operationId": "PlanController.deleteById" } }, - "/services": { + "/plans": { "post": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "create", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1802,32 +1907,34 @@ ], "responses": { "200": { - "description": "Service model instance", + "description": "Plan model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Service" + "$ref": "#/components/schemas/Plan" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7017 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7005 |\n", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewService" + "$ref": "#/components/schemas/NewPlan" } } } }, - "operationId": "ServiceController.create" + "operationId": "PlanController.create" }, "patch": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "updateAll", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1835,7 +1942,7 @@ ], "responses": { "200": { - "description": "Service PATCH success count", + "description": "Plan PATCH success count", "content": { "application/json": { "schema": { @@ -1845,7 +1952,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7006 |\n", "parameters": [ { "name": "where", @@ -1854,9 +1961,9 @@ "application/json": { "schema": { "type": "object", - "title": "services.WhereFilter", + "title": "plans.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } @@ -1866,17 +1973,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServicePartial" + "$ref": "#/components/schemas/PlanPartial" } } } }, - "operationId": "ServiceController.updateAll" + "operationId": "PlanController.updateAll" }, "get": { - "x-controller-name": "ServiceController", + "x-controller-name": "PlanController", "x-operation-name": "find", - "tags": ["ServiceController"], + "tags": [ + "PlanController" + ], "security": [ { "HTTPBearer": [] @@ -1884,20 +1993,20 @@ ], "responses": { "200": { - "description": "Array of Service model instances", + "description": "Array of Plan model instances", "content": { "application/json": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceWithRelations" + "$ref": "#/components/schemas/PlanWithRelations" } } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7008 |\n", "parameters": [ { "name": "filter", @@ -1905,20 +2014,22 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/services.Filter1" + "$ref": "#/components/schemas/plans.Filter1" } } } } ], - "operationId": "ServiceController.find" + "operationId": "PlanController.find" } }, - "/subscriptions/count": { + "/resources/count": { "get": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "count", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -1926,7 +2037,7 @@ ], "responses": { "200": { - "description": "Subscription model count", + "description": "Resource model count", "content": { "application/json": { "schema": { @@ -1936,7 +2047,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "where", @@ -1945,22 +2056,24 @@ "application/json": { "schema": { "type": "object", - "title": "subscriptions.WhereFilter", + "title": "resources.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } } ], - "operationId": "SubscriptionController.count" + "operationId": "ResourceController.count" } }, - "/subscriptions/{id}": { + "/resources/{id}": { "put": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "replaceById", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -1968,10 +2081,10 @@ ], "responses": { "204": { - "description": "Subscription PUT success" + "description": "Resource PUT success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "id", @@ -1986,18 +2099,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subscription" + "$ref": "#/components/schemas/Resource" } } }, "x-parameter-index": 1 }, - "operationId": "SubscriptionController.replaceById" + "operationId": "ResourceController.replaceById" }, "patch": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "updateById", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2005,10 +2120,10 @@ ], "responses": { "204": { - "description": "Subscription PATCH success" + "description": "Resource PATCH success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "id", @@ -2023,18 +2138,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscriptionPartial" + "$ref": "#/components/schemas/ResourcePartial" } } }, "x-parameter-index": 1 }, - "operationId": "SubscriptionController.updateById" + "operationId": "ResourceController.updateById" }, "get": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "findById", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2042,17 +2159,17 @@ ], "responses": { "200": { - "description": "Subscription model instance", + "description": "Resource model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscriptionWithRelations" + "$ref": "#/components/schemas/ResourceWithRelations" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "id", @@ -2068,18 +2185,20 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/subscriptions.Filter" + "$ref": "#/components/schemas/resources.Filter" } } } } ], - "operationId": "SubscriptionController.findById" + "operationId": "ResourceController.findById" }, "delete": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "deleteById", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2087,10 +2206,10 @@ ], "responses": { "204": { - "description": "Subscription DELETE success" + "description": "Resource DELETE success" } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7003 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7015 |\n", "parameters": [ { "name": "id", @@ -2101,14 +2220,16 @@ "required": true } ], - "operationId": "SubscriptionController.deleteById" + "operationId": "ResourceController.deleteById" } }, - "/subscriptions": { + "/resources": { "post": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "create", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2116,32 +2237,34 @@ ], "responses": { "200": { - "description": "Subscription model instance", + "description": "Resource model instance", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subscription" + "$ref": "#/components/schemas/Resource" } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7001 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7013 |\n", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewSubscription" + "$ref": "#/components/schemas/NewResource" } } } }, - "operationId": "SubscriptionController.create" + "operationId": "ResourceController.create" }, "patch": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "updateAll", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2149,7 +2272,7 @@ ], "responses": { "200": { - "description": "Subscription PATCH success count", + "description": "Resource PATCH success count", "content": { "application/json": { "schema": { @@ -2159,7 +2282,7 @@ } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7014 |\n", "parameters": [ { "name": "where", @@ -2168,9 +2291,9 @@ "application/json": { "schema": { "type": "object", - "title": "subscriptions.WhereFilter", + "title": "resources.WhereFilter", "additionalProperties": true, - "x-typescript-type": "@loopback/repository#Where" + "x-typescript-type": "@loopback/repository#Where" } } } @@ -2180,17 +2303,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscriptionPartial" + "$ref": "#/components/schemas/ResourcePartial" } } } }, - "operationId": "SubscriptionController.updateAll" + "operationId": "ResourceController.updateAll" }, "get": { - "x-controller-name": "SubscriptionController", + "x-controller-name": "ResourceController", "x-operation-name": "find", - "tags": ["SubscriptionController"], + "tags": [ + "ResourceController" + ], "security": [ { "HTTPBearer": [] @@ -2198,20 +2323,20 @@ ], "responses": { "200": { - "description": "Array of Subscription model instances", + "description": "Array of Resource model instances", "content": { "application/json": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/SubscriptionWithRelations" + "$ref": "#/components/schemas/ResourceWithRelations" } } } } } }, - "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "description": "\n\n| Permissions |\n| ------- |\n| 7016 |\n", "parameters": [ { "name": "filter", @@ -2219,38 +2344,1125 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/subscriptions.Filter1" + "$ref": "#/components/schemas/resources.Filter1" } } } } ], - "operationId": "SubscriptionController.find" + "operationId": "ResourceController.find" } }, - "/": { + "/services/count": { "get": { - "x-controller-name": "HomePageController", - "x-operation-name": "homePage", - "tags": ["HomePageController"], + "x-controller-name": "ServiceController", + "x-operation-name": "count", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], "responses": { "200": { - "description": "Home Page", + "description": "Service model count", "content": { - "text/html": { + "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/loopback.Count" } } } } }, - "description": "", - "operationId": "HomePageController.homePage" + "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "services.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "operationId": "ServiceController.count" } - } - }, - "components": { + }, + "/services/{id}": { + "put": { + "x-controller-name": "ServiceController", + "x-operation-name": "replaceById", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Service PUT success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "ServiceController.replaceById" + }, + "patch": { + "x-controller-name": "ServiceController", + "x-operation-name": "updateById", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Service PATCH success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServicePartial" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "ServiceController.updateById" + }, + "get": { + "x-controller-name": "ServiceController", + "x-operation-name": "findById", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Service model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceWithRelations" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/services.Filter" + } + } + } + } + ], + "operationId": "ServiceController.findById" + }, + "delete": { + "x-controller-name": "ServiceController", + "x-operation-name": "deleteById", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Service DELETE success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7019 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "operationId": "ServiceController.deleteById" + } + }, + "/services": { + "post": { + "x-controller-name": "ServiceController", + "x-operation-name": "create", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Service model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7017 |\n", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewService" + } + } + } + }, + "operationId": "ServiceController.create" + }, + "patch": { + "x-controller-name": "ServiceController", + "x-operation-name": "updateAll", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Service PATCH success count", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/loopback.Count" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7018 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "services.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServicePartial" + } + } + } + }, + "operationId": "ServiceController.updateAll" + }, + "get": { + "x-controller-name": "ServiceController", + "x-operation-name": "find", + "tags": [ + "ServiceController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Array of Service model instances", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceWithRelations" + } + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7020 |\n", + "parameters": [ + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/services.Filter1" + } + } + } + } + ], + "operationId": "ServiceController.find" + } + }, + "/strategies/count": { + "get": { + "x-controller-name": "StrategyController", + "x-operation-name": "count", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Strategy model count", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/loopback.Count" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| ViewStrategy |\n| 5 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "strategies.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "operationId": "StrategyController.count" + } + }, + "/strategies/{id}": { + "put": { + "x-controller-name": "StrategyController", + "x-operation-name": "replaceById", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Strategy PUT success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| UpdateStrategy |\n| 7 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Strategy" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "StrategyController.replaceById" + }, + "patch": { + "x-controller-name": "StrategyController", + "x-operation-name": "updateById", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Strategy PATCH success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| UpdateStrategy |\n| 7 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StrategyPartial" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "StrategyController.updateById" + }, + "get": { + "x-controller-name": "StrategyController", + "x-operation-name": "findById", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Strategy model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StrategyWithRelations" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| ViewStrategy |\n| 5 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/strategies.Filter" + } + } + } + } + ], + "operationId": "StrategyController.findById" + }, + "delete": { + "x-controller-name": "StrategyController", + "x-operation-name": "deleteById", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Strategy DELETE success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| DeleteStrategy |\n| 8 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "operationId": "StrategyController.deleteById" + } + }, + "/strategies": { + "post": { + "x-controller-name": "StrategyController", + "x-operation-name": "create", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Strategy model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Strategy" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| CreateStrategy |\n| 6 |\n", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewStrategy" + } + } + } + }, + "operationId": "StrategyController.create" + }, + "patch": { + "x-controller-name": "StrategyController", + "x-operation-name": "updateAll", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Strategy PATCH success count", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/loopback.Count" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| UpdateStrategy |\n| 7 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "strategies.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StrategyPartial" + } + } + } + }, + "operationId": "StrategyController.updateAll" + }, + "get": { + "x-controller-name": "StrategyController", + "x-operation-name": "find", + "tags": [ + "StrategyController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Array of Strategy model instances", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StrategyWithRelations" + } + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| ViewStrategy |\n| 5 |\n", + "parameters": [ + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/strategies.Filter1" + } + } + } + } + ], + "operationId": "StrategyController.find" + } + }, + "/subscriptions/count": { + "get": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "count", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Subscription model count", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/loopback.Count" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "subscriptions.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "operationId": "SubscriptionController.count" + } + }, + "/subscriptions/expire-soon": { + "get": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "expireSoonSubscription", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Array of Subscription model instances", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubscriptionWithRelations" + } + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "parameters": [ + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/subscriptions.Filter" + } + } + } + } + ], + "operationId": "SubscriptionController.expireSoonSubscription" + } + }, + "/subscriptions/expired": { + "get": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "expiredSubscription", + "tags": [ + "SubscriptionController" + ], + "description": "api that will return newly expired subscription\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Array of Subscription model instances", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubscriptionWithRelations" + } + } + } + } + } + }, + "parameters": [ + { + "name": "days", + "in": "header", + "schema": { + "type": "number" + } + }, + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/subscriptions.Filter" + } + } + } + } + ], + "operationId": "SubscriptionController.expiredSubscription" + } + }, + "/subscriptions/{id}": { + "put": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "replaceById", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Subscription PUT success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Subscription" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "SubscriptionController.replaceById" + }, + "patch": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "updateById", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Subscription PATCH success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionPartial" + } + } + }, + "x-parameter-index": 1 + }, + "operationId": "SubscriptionController.updateById" + }, + "get": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "findById", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Subscription model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionWithRelations" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/subscriptions.Filter1" + } + } + } + } + ], + "operationId": "SubscriptionController.findById" + }, + "delete": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "deleteById", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "204": { + "description": "Subscription DELETE success" + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7003 |\n", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "operationId": "SubscriptionController.deleteById" + } + }, + "/subscriptions": { + "post": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "create", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Subscription model instance", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Subscription" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7001 |\n", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewSubscription" + } + } + } + }, + "operationId": "SubscriptionController.create" + }, + "patch": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "updateAll", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Subscription PATCH success count", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/loopback.Count" + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7002 |\n", + "parameters": [ + { + "name": "where", + "in": "query", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "subscriptions.WhereFilter", + "additionalProperties": true, + "x-typescript-type": "@loopback/repository#Where" + } + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionPartial" + } + } + } + }, + "operationId": "SubscriptionController.updateAll" + }, + "get": { + "x-controller-name": "SubscriptionController", + "x-operation-name": "find", + "tags": [ + "SubscriptionController" + ], + "security": [ + { + "HTTPBearer": [] + } + ], + "responses": { + "200": { + "description": "Array of Subscription model instances", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubscriptionWithRelations" + } + } + } + } + } + }, + "description": "\n\n| Permissions |\n| ------- |\n| 7004 |\n", + "parameters": [ + { + "name": "filter", + "in": "query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/subscriptions.Filter" + } + } + } + } + ], + "operationId": "SubscriptionController.find" + } + }, + "/": { + "get": { + "x-controller-name": "HomePageController", + "x-operation-name": "homePage", + "tags": [ + "HomePageController" + ], + "responses": { + "200": { + "description": "Home Page", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + } + }, + "description": "", + "operationId": "HomePageController.homePage" + } + } + }, + "components": { "securitySchemes": { "HTTPBearer": { "type": "http", @@ -2259,9 +3471,346 @@ } }, "schemas": { - "Subscription": { - "title": "Subscription", + "Feature": { + "title": "Feature", + "type": "object", + "description": "The features table", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": { + "type": "object" + } + }, + "required": [ + "name", + "key" + ], + "additionalProperties": false + }, + "NewFeature": { + "title": "NewFeature", + "type": "object", + "description": "The features table (tsType: Feature, schemaOptions: { title: 'NewFeature' })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": { + "type": "object" + } + }, + "required": [ + "name", + "key" + ], + "additionalProperties": false + }, + "FeatureWithRelations": { + "title": "FeatureWithRelations", + "type": "object", + "description": "The features table (tsType: FeatureWithRelations, schemaOptions: { includeRelations: true })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": { + "type": "object" + } + }, + "required": [ + "name", + "key" + ], + "additionalProperties": false + }, + "FeaturePartial": { + "title": "FeaturePartial", + "type": "object", + "description": "The features table (tsType: Partial, schemaOptions: { partial: true })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": { + "type": "object" + } + }, + "additionalProperties": false + }, + "FeatureValues": { + "title": "FeatureValues", + "type": "object", + "description": "The feature-values table", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "featureKey": { + "type": "string" + }, + "strategyKey": { + "type": "string" + }, + "strategyEntityId": { + "type": "string" + }, + "status": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NewFeatureValues": { + "title": "NewFeatureValues", + "type": "object", + "description": "The feature-values table (tsType: FeatureValues, schemaOptions: { title: 'NewFeatureValues' })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "featureKey": { + "type": "string" + }, + "strategyKey": { + "type": "string" + }, + "strategyEntityId": { + "type": "string" + }, + "status": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": false + }, + "FeatureValuesWithRelations": { + "title": "FeatureValuesWithRelations", "type": "object", + "description": "The feature-values table (tsType: FeatureValuesWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -2292,32 +3841,28 @@ "id": { "type": "string" }, - "subscriberId": { + "featureKey": { "type": "string" }, - "startDate": { + "strategyKey": { "type": "string" }, - "endDate": { + "strategyEntityId": { "type": "string" }, "status": { - "type": "number", - "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", - "enum": [0, 1, 2, 3, 4] + "type": "boolean" }, - "planId": { - "type": "string", - "description": "plan id of the subscription" + "value": { + "type": "string" } }, - "required": ["subscriberId", "startDate", "endDate", "status"], "additionalProperties": false }, - "NewSubscription": { - "title": "NewSubscription", + "FeatureValuesPartial": { + "title": "FeatureValuesPartial", "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewSubscription', exclude: [ 'id' ] })", + "description": "The feature-values table (tsType: Partial, schemaOptions: { partial: true })", "properties": { "deleted": { "type": "boolean" @@ -2345,33 +3890,131 @@ "modifiedBy": { "type": "string" }, - "subscriberId": { + "id": { "type": "string" }, - "startDate": { + "featureKey": { "type": "string" }, - "endDate": { + "strategyKey": { + "type": "string" + }, + "strategyEntityId": { "type": "string" }, "status": { - "type": "number", - "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", - "enum": [0, 1, 2, 3, 4] + "type": "boolean" }, - "planId": { + "value": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Strategy": { + "title": "Strategy", + "type": "object", + "description": "The strategies table", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { "type": "string", - "description": "plan id of the subscription" + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "priority": { + "type": "number" } }, - "required": ["subscriberId", "startDate", "endDate", "status"], - "additionalProperties": false, - "x-typescript-type": "Omit" + "required": [ + "name", + "key" + ], + "additionalProperties": false + }, + "NewStrategy": { + "title": "NewStrategy", + "type": "object", + "description": "The strategies table (tsType: Strategy, schemaOptions: { title: 'NewStrategy' })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "priority": { + "type": "number" + } + }, + "required": [ + "name", + "key" + ], + "additionalProperties": false }, - "PlanItemWithRelations": { - "title": "PlanItemWithRelations", + "StrategyWithRelations": { + "title": "StrategyWithRelations", "type": "object", - "description": "(tsType: PlanItemWithRelations, schemaOptions: { includeRelations: true })", + "description": "The strategies table (tsType: StrategyWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -2403,34 +4046,70 @@ "type": "string" }, "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "priority": { + "type": "number" + } + }, + "required": [ + "name", + "key" + ], + "additionalProperties": false + }, + "StrategyPartial": { + "title": "StrategyPartial", + "type": "object", + "description": "The strategies table (tsType: Partial, schemaOptions: { partial: true })", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { "type": "string", - "description": "name of the plan item" + "format": "date-time", + "nullable": true }, - "planItemType": { + "deletedBy": { "type": "string", - "description": "type of the plan item" + "nullable": true }, - "value": { - "type": "object", - "description": "value of the plan item" + "createdOn": { + "type": "string", + "format": "date-time" }, - "planId": { + "modifiedOn": { "type": "string", - "description": "plan id of the plan item" + "format": "date-time" }, - "plan": { - "$ref": "#/components/schemas/PlanWithRelations" + "createdBy": { + "type": "string" }, - "foreignKey": {} + "modifiedBy": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "priority": { + "type": "number" + } }, - "required": ["name", "planItemType", "value"], - "additionalProperties": false, - "x-typescript-type": "PlanItemWithRelations" + "additionalProperties": false }, - "BillingCycleWithRelations": { - "title": "BillingCycleWithRelations", + "BillingCycle": { + "title": "BillingCycle", "type": "object", - "description": "(tsType: BillingCycleWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -2474,39 +4153,69 @@ "type": "string" } }, - "required": ["cycleName", "duration", "durationUnit"], - "additionalProperties": false, - "x-typescript-type": "BillingCycleWithRelations" + "required": [ + "cycleName", + "duration", + "durationUnit" + ], + "additionalProperties": false }, - "CurrencyWithRelations": { - "title": "CurrencyWithRelations", + "NewBillingCycle": { + "title": "NewBillingCycle", "type": "object", - "description": "(tsType: CurrencyWithRelations, schemaOptions: { includeRelations: true })", + "description": "(tsType: Omit, schemaOptions: { title: 'NewBillingCycle', exclude: [ 'id' ] })", "properties": { - "id": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "deletedBy": { + "type": "string", + "nullable": true + }, + "createdOn": { + "type": "string", + "format": "date-time" + }, + "modifiedOn": { + "type": "string", + "format": "date-time" + }, + "createdBy": { "type": "string" }, - "currencyCode": { + "modifiedBy": { "type": "string" }, - "currencyName": { + "cycleName": { "type": "string" }, - "symbol": { + "duration": { + "type": "number" + }, + "durationUnit": { "type": "string" }, - "country": { + "description": { "type": "string" } }, - "required": ["currencyCode", "currencyName"], + "required": [ + "cycleName", + "duration", + "durationUnit" + ], "additionalProperties": false, - "x-typescript-type": "CurrencyWithRelations" + "x-typescript-type": "Omit" }, - "PlanWithRelations": { - "title": "PlanWithRelations", + "BillingCycleWithRelations": { + "title": "BillingCycleWithRelations", "type": "object", - "description": "(tsType: PlanWithRelations, schemaOptions: { includeRelations: true })", + "description": "(tsType: BillingCycleWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -2537,54 +4246,31 @@ "id": { "type": "string" }, - "name": { - "type": "string", - "description": "name of the plan" - }, - "description": { - "type": "string", - "description": "description of the plan" - }, - "tier": { - "type": "number", - "description": "Tier of the plan, it can be - 0(Pooled) and 1(Silo)", - "enum": [0, 1] + "cycleName": { + "type": "string" }, - "price": { + "duration": { "type": "number" }, - "metaData": { - "type": "object", - "description": "Meta data of the plan" - }, - "billingCycleId": { + "durationUnit": { "type": "string" }, - "currencyId": { + "description": { "type": "string" - }, - "planItems": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PlanItemWithRelations" - } - }, - "billingCycle": { - "$ref": "#/components/schemas/BillingCycleWithRelations" - }, - "foreignKey": {}, - "currency": { - "$ref": "#/components/schemas/CurrencyWithRelations" } }, - "required": ["name", "description", "tier", "price"], + "required": [ + "cycleName", + "duration", + "durationUnit" + ], "additionalProperties": false, - "x-typescript-type": "PlanWithRelations" + "x-typescript-type": "BillingCycleWithRelations" }, - "SubscriptionWithRelations": { - "title": "SubscriptionWithRelations", + "BillingCyclePartial": { + "title": "BillingCyclePartial", "type": "object", - "description": "(tsType: SubscriptionWithRelations, schemaOptions: { includeRelations: true })", + "description": "(tsType: Partial, schemaOptions: { partial: true })", "properties": { "deleted": { "type": "boolean" @@ -2615,91 +4301,127 @@ "id": { "type": "string" }, - "subscriberId": { + "cycleName": { "type": "string" }, - "startDate": { + "duration": { + "type": "number" + }, + "durationUnit": { "type": "string" }, - "endDate": { + "description": { + "type": "string" + } + }, + "additionalProperties": false, + "x-typescript-type": "Partial" + }, + "Currency": { + "title": "Currency", + "type": "object", + "properties": { + "id": { "type": "string" }, - "status": { - "type": "number", - "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", - "enum": [0, 1, 2, 3, 4] + "currencyCode": { + "type": "string" }, - "planId": { - "type": "string", - "description": "plan id of the subscription" + "currencyName": { + "type": "string" }, - "plan": { - "$ref": "#/components/schemas/PlanWithRelations" + "symbol": { + "type": "string" }, - "foreignKey": {} + "country": { + "type": "string" + } }, - "required": ["subscriberId", "startDate", "endDate", "status"], - "additionalProperties": false, - "x-typescript-type": "SubscriptionWithRelations" + "required": [ + "currencyCode", + "currencyName" + ], + "additionalProperties": false }, - "SubscriptionPartial": { - "title": "SubscriptionPartial", + "NewCurrency": { + "title": "NewCurrency", "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", + "description": "(tsType: Omit, schemaOptions: { title: 'NewCurrency', exclude: [ 'id' ] })", "properties": { - "deleted": { - "type": "boolean" + "currencyCode": { + "type": "string" }, - "deletedOn": { - "type": "string", - "format": "date-time", - "nullable": true + "currencyName": { + "type": "string" }, - "deletedBy": { - "type": "string", - "nullable": true + "symbol": { + "type": "string" }, - "createdOn": { - "type": "string", - "format": "date-time" + "country": { + "type": "string" + } + }, + "required": [ + "currencyCode", + "currencyName" + ], + "additionalProperties": false, + "x-typescript-type": "Omit" + }, + "CurrencyWithRelations": { + "title": "CurrencyWithRelations", + "type": "object", + "description": "(tsType: CurrencyWithRelations, schemaOptions: { includeRelations: true })", + "properties": { + "id": { + "type": "string" }, - "modifiedOn": { - "type": "string", - "format": "date-time" + "currencyCode": { + "type": "string" }, - "createdBy": { + "currencyName": { "type": "string" }, - "modifiedBy": { + "symbol": { "type": "string" }, + "country": { + "type": "string" + } + }, + "required": [ + "currencyCode", + "currencyName" + ], + "additionalProperties": false, + "x-typescript-type": "CurrencyWithRelations" + }, + "CurrencyPartial": { + "title": "CurrencyPartial", + "type": "object", + "description": "(tsType: Partial, schemaOptions: { partial: true })", + "properties": { "id": { "type": "string" }, - "subscriberId": { + "currencyCode": { "type": "string" }, - "startDate": { + "currencyName": { "type": "string" }, - "endDate": { + "symbol": { "type": "string" }, - "status": { - "type": "number", - "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", - "enum": [0, 1, 2, 3, 4] - }, - "planId": { - "type": "string", - "description": "plan id of the subscription" + "country": { + "type": "string" } }, "additionalProperties": false, - "x-typescript-type": "Partial" + "x-typescript-type": "Partial" }, - "Service": { - "title": "Service", + "Plan": { + "title": "Plan", "type": "object", "properties": { "deleted": { @@ -2733,16 +4455,42 @@ }, "name": { "type": "string", - "description": "name of the service" + "description": "name of the plan" + }, + "description": { + "type": "string", + "description": "description of the plan" + }, + "tier": { + "type": "string", + "description": "Tier of the plan." + }, + "price": { + "type": "number" + }, + "metaData": { + "type": "object", + "description": "Meta data of the plan" + }, + "billingCycleId": { + "type": "string" + }, + "currencyId": { + "type": "string" } }, - "required": ["name"], + "required": [ + "name", + "description", + "tier", + "price" + ], "additionalProperties": false }, - "NewService": { - "title": "NewService", + "NewPlan": { + "title": "NewPlan", "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewService', exclude: [ 'id' ] })", + "description": "(tsType: Omit, schemaOptions: { title: 'NewPlan', exclude: [ 'id' ] })", "properties": { "deleted": { "type": "boolean" @@ -2772,17 +4520,43 @@ }, "name": { "type": "string", - "description": "name of the service" + "description": "name of the plan" + }, + "description": { + "type": "string", + "description": "description of the plan" + }, + "tier": { + "type": "string", + "description": "Tier of the plan." + }, + "price": { + "type": "number" + }, + "metaData": { + "type": "object", + "description": "Meta data of the plan" + }, + "billingCycleId": { + "type": "string" + }, + "currencyId": { + "type": "string" } }, - "required": ["name"], + "required": [ + "name", + "description", + "tier", + "price" + ], "additionalProperties": false, - "x-typescript-type": "Omit" + "x-typescript-type": "Omit" }, - "ServiceWithRelations": { - "title": "ServiceWithRelations", + "PlanWithRelations": { + "title": "PlanWithRelations", "type": "object", - "description": "(tsType: ServiceWithRelations, schemaOptions: { includeRelations: true })", + "description": "(tsType: PlanWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -2815,17 +4589,50 @@ }, "name": { "type": "string", - "description": "name of the service" + "description": "name of the plan" + }, + "description": { + "type": "string", + "description": "description of the plan" + }, + "tier": { + "type": "string", + "description": "Tier of the plan." + }, + "price": { + "type": "number" + }, + "metaData": { + "type": "object", + "description": "Meta data of the plan" + }, + "billingCycleId": { + "type": "string" + }, + "currencyId": { + "type": "string" + }, + "billingCycle": { + "$ref": "#/components/schemas/BillingCycleWithRelations" + }, + "foreignKey": {}, + "currency": { + "$ref": "#/components/schemas/CurrencyWithRelations" } }, - "required": ["name"], + "required": [ + "name", + "description", + "tier", + "price" + ], "additionalProperties": false, - "x-typescript-type": "ServiceWithRelations" + "x-typescript-type": "PlanWithRelations" }, - "ServicePartial": { - "title": "ServicePartial", + "PlanPartial": { + "title": "PlanPartial", "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", + "description": "(tsType: Partial, schemaOptions: { partial: true })", "properties": { "deleted": { "type": "boolean" @@ -2858,11 +4665,32 @@ }, "name": { "type": "string", - "description": "name of the service" + "description": "name of the plan" + }, + "description": { + "type": "string", + "description": "description of the plan" + }, + "tier": { + "type": "string", + "description": "Tier of the plan." + }, + "price": { + "type": "number" + }, + "metaData": { + "type": "object", + "description": "Meta data of the plan" + }, + "billingCycleId": { + "type": "string" + }, + "currencyId": { + "type": "string" } }, "additionalProperties": false, - "x-typescript-type": "Partial" + "x-typescript-type": "Partial" }, "Resource": { "title": "Resource", @@ -2906,7 +4734,10 @@ "description": "config of the resource" } }, - "required": ["name", "config"], + "required": [ + "name", + "config" + ], "additionalProperties": false }, "NewResource": { @@ -2949,7 +4780,10 @@ "description": "config of the resource" } }, - "required": ["name", "config"], + "required": [ + "name", + "config" + ], "additionalProperties": false, "x-typescript-type": "Omit" }, @@ -2996,7 +4830,10 @@ "description": "config of the resource" } }, - "required": ["name", "config"], + "required": [ + "name", + "config" + ], "additionalProperties": false, "x-typescript-type": "ResourceWithRelations" }, @@ -3046,8 +4883,8 @@ "additionalProperties": false, "x-typescript-type": "Partial" }, - "Plan": { - "title": "Plan", + "Service": { + "title": "Service", "type": "object", "properties": { "deleted": { @@ -3081,38 +4918,60 @@ }, "name": { "type": "string", - "description": "name of the plan" + "description": "name of the service" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "NewService": { + "title": "NewService", + "type": "object", + "description": "(tsType: Omit, schemaOptions: { title: 'NewService', exclude: [ 'id' ] })", + "properties": { + "deleted": { + "type": "boolean" }, - "description": { + "deletedOn": { "type": "string", - "description": "description of the plan" + "format": "date-time", + "nullable": true }, - "tier": { - "type": "number", - "description": "Tier of the plan, it can be - 0(Pooled) and 1(Silo)", - "enum": [0, 1] + "deletedBy": { + "type": "string", + "nullable": true }, - "price": { - "type": "number" + "createdOn": { + "type": "string", + "format": "date-time" }, - "metaData": { - "type": "object", - "description": "Meta data of the plan" + "modifiedOn": { + "type": "string", + "format": "date-time" }, - "billingCycleId": { + "createdBy": { "type": "string" }, - "currencyId": { + "modifiedBy": { "type": "string" + }, + "name": { + "type": "string", + "description": "name of the service" } }, - "required": ["name", "description", "tier", "price"], - "additionalProperties": false + "required": [ + "name" + ], + "additionalProperties": false, + "x-typescript-type": "Omit" }, - "NewPlan": { - "title": "NewPlan", + "ServiceWithRelations": { + "title": "ServiceWithRelations", "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewPlan', exclude: [ 'id' ] })", + "description": "(tsType: ServiceWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -3140,41 +4999,65 @@ "modifiedBy": { "type": "string" }, + "id": { + "type": "string" + }, "name": { "type": "string", - "description": "name of the plan" + "description": "name of the service" + } + }, + "required": [ + "name" + ], + "additionalProperties": false, + "x-typescript-type": "ServiceWithRelations" + }, + "ServicePartial": { + "title": "ServicePartial", + "type": "object", + "description": "(tsType: Partial, schemaOptions: { partial: true })", + "properties": { + "deleted": { + "type": "boolean" }, - "description": { + "deletedOn": { "type": "string", - "description": "description of the plan" + "format": "date-time", + "nullable": true }, - "tier": { - "type": "number", - "description": "Tier of the plan, it can be - 0(Pooled) and 1(Silo)", - "enum": [0, 1] + "deletedBy": { + "type": "string", + "nullable": true }, - "price": { - "type": "number" + "createdOn": { + "type": "string", + "format": "date-time" }, - "metaData": { - "type": "object", - "description": "Meta data of the plan" + "modifiedOn": { + "type": "string", + "format": "date-time" }, - "billingCycleId": { + "createdBy": { "type": "string" }, - "currencyId": { + "modifiedBy": { + "type": "string" + }, + "id": { "type": "string" + }, + "name": { + "type": "string", + "description": "name of the service" } }, - "required": ["name", "description", "tier", "price"], "additionalProperties": false, - "x-typescript-type": "Omit" + "x-typescript-type": "Partial" }, - "PlanPartial": { - "title": "PlanPartial", + "Subscription": { + "title": "Subscription", "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", "properties": { "deleted": { "type": "boolean" @@ -3205,39 +5088,43 @@ "id": { "type": "string" }, - "name": { - "type": "string", - "description": "name of the plan" - }, - "description": { - "type": "string", - "description": "description of the plan" - }, - "tier": { - "type": "number", - "description": "Tier of the plan, it can be - 0(Pooled) and 1(Silo)", - "enum": [0, 1] - }, - "price": { - "type": "number" - }, - "metaData": { - "type": "object", - "description": "Meta data of the plan" + "subscriberId": { + "type": "string" }, - "billingCycleId": { + "startDate": { "type": "string" }, - "currencyId": { + "endDate": { "type": "string" + }, + "status": { + "type": "number", + "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", + "enum": [ + 0, + 1, + 2, + 3, + 4 + ] + }, + "planId": { + "type": "string", + "description": "plan id of the subscription" } }, - "additionalProperties": false, - "x-typescript-type": "Partial" + "required": [ + "subscriberId", + "startDate", + "endDate", + "status" + ], + "additionalProperties": false }, - "PlanItem": { - "title": "PlanItem", + "NewSubscription": { + "title": "NewSubscription", "type": "object", + "description": "(tsType: Omit, schemaOptions: { title: 'NewSubscription', exclude: [ 'id', 'startDate', 'endDate' ] })", "properties": { "deleted": { "type": "boolean" @@ -3265,33 +5152,36 @@ "modifiedBy": { "type": "string" }, - "id": { + "subscriberId": { "type": "string" }, - "name": { - "type": "string", - "description": "name of the plan item" - }, - "planItemType": { - "type": "string", - "description": "type of the plan item" - }, - "value": { - "type": "object", - "description": "value of the plan item" + "status": { + "type": "number", + "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", + "enum": [ + 0, + 1, + 2, + 3, + 4 + ] }, "planId": { "type": "string", - "description": "plan id of the plan item" + "description": "plan id of the subscription" } }, - "required": ["name", "planItemType", "value"], - "additionalProperties": false + "required": [ + "subscriberId", + "status" + ], + "additionalProperties": false, + "x-typescript-type": "Omit" }, - "NewPlanItem": { - "title": "NewPlanItem", + "SubscriptionWithRelations": { + "title": "SubscriptionWithRelations", "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewPlanItem', exclude: [ 'id' ] })", + "description": "(tsType: SubscriptionWithRelations, schemaOptions: { includeRelations: true })", "properties": { "deleted": { "type": "boolean" @@ -3319,31 +5209,51 @@ "modifiedBy": { "type": "string" }, - "name": { - "type": "string", - "description": "name of the plan item" + "id": { + "type": "string" }, - "planItemType": { - "type": "string", - "description": "type of the plan item" + "subscriberId": { + "type": "string" }, - "value": { - "type": "object", - "description": "value of the plan item" + "startDate": { + "type": "string" + }, + "endDate": { + "type": "string" + }, + "status": { + "type": "number", + "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", + "enum": [ + 0, + 1, + 2, + 3, + 4 + ] }, "planId": { "type": "string", - "description": "plan id of the plan item" - } + "description": "plan id of the subscription" + }, + "plan": { + "$ref": "#/components/schemas/PlanWithRelations" + }, + "foreignKey": {} }, - "required": ["name", "planItemType", "value"], + "required": [ + "subscriberId", + "startDate", + "endDate", + "status" + ], "additionalProperties": false, - "x-typescript-type": "Omit" + "x-typescript-type": "SubscriptionWithRelations" }, - "PlanItemPartial": { - "title": "PlanItemPartial", + "SubscriptionPartial": { + "title": "SubscriptionPartial", "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", + "description": "(tsType: Partial, schemaOptions: { partial: true })", "properties": { "deleted": { "type": "boolean" @@ -3374,255 +5284,489 @@ "id": { "type": "string" }, - "name": { - "type": "string", - "description": "name of the plan item" + "subscriberId": { + "type": "string" }, - "planItemType": { - "type": "string", - "description": "type of the plan item" + "startDate": { + "type": "string" }, - "value": { - "type": "object", - "description": "value of the plan item" + "endDate": { + "type": "string" + }, + "status": { + "type": "number", + "description": "status of the subscription, it can be - 0(pending), 1(active), 2(inactive), 3(cancelled) and 4(expired)", + "enum": [ + 0, + 1, + 2, + 3, + 4 + ] }, "planId": { "type": "string", - "description": "plan id of the plan item" + "description": "plan id of the subscription" } }, "additionalProperties": false, - "x-typescript-type": "Partial" + "x-typescript-type": "Partial" }, - "Currency": { - "title": "Currency", + "PlanSizes": { + "title": "PlanSizes", "type": "object", "properties": { "id": { "type": "string" }, - "currencyCode": { - "type": "string" - }, - "currencyName": { - "type": "string" - }, - "symbol": { + "size": { "type": "string" }, - "country": { - "type": "string" + "config": { + "type": "object" } }, - "required": ["currencyCode", "currencyName"], + "required": [ + "size" + ], "additionalProperties": false }, - "NewCurrency": { - "title": "NewCurrency", + "NewPlanSizes": { + "title": "NewPlanSizes", "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewCurrency', exclude: [ 'id' ] })", + "description": "(tsType: Omit, schemaOptions: { title: 'NewPlanSizes', exclude: [ 'id' ] })", "properties": { - "currencyCode": { - "type": "string" - }, - "currencyName": { + "size": { "type": "string" }, - "symbol": { - "type": "string" - }, - "country": { - "type": "string" + "config": { + "type": "object" } }, - "required": ["currencyCode", "currencyName"], + "required": [ + "size" + ], "additionalProperties": false, - "x-typescript-type": "Omit" + "x-typescript-type": "Omit" }, - "CurrencyPartial": { - "title": "CurrencyPartial", + "PlanSizesWithRelations": { + "title": "PlanSizesWithRelations", "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", + "description": "(tsType: PlanSizesWithRelations, schemaOptions: { includeRelations: true })", "properties": { "id": { "type": "string" }, - "currencyCode": { + "size": { "type": "string" }, - "currencyName": { + "config": { + "type": "object" + } + }, + "required": [ + "size" + ], + "additionalProperties": false, + "x-typescript-type": "PlanSizesWithRelations" + }, + "PlanSizesPartial": { + "title": "PlanSizesPartial", + "type": "object", + "description": "(tsType: Partial, schemaOptions: { partial: true })", + "properties": { + "id": { "type": "string" }, - "symbol": { + "size": { "type": "string" }, - "country": { - "type": "string" + "config": { + "type": "object" } }, "additionalProperties": false, - "x-typescript-type": "Partial" + "x-typescript-type": "Partial" }, - "BillingCycle": { - "title": "BillingCycle", + "loopback.Count": { "type": "object", + "title": "loopback.Count", + "x-typescript-type": "@loopback/repository#Count", "properties": { - "deleted": { - "type": "boolean" - }, - "deletedOn": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "deletedBy": { - "type": "string", - "nullable": true + "count": { + "type": "number" + } + } + }, + "billing_cycles.Filter": { + "type": "object", + "title": "billing_cycles.Filter", + "properties": { + "offset": { + "type": "integer", + "minimum": 0 }, - "createdOn": { - "type": "string", - "format": "date-time" + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 }, - "modifiedOn": { - "type": "string", - "format": "date-time" + "skip": { + "type": "integer", + "minimum": 0 }, - "createdBy": { - "type": "string" + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] }, - "modifiedBy": { - "type": "string" + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, + "id": { + "type": "boolean" + }, + "cycleName": { + "type": "boolean" + }, + "duration": { + "type": "boolean" + }, + "durationUnit": { + "type": "boolean" + }, + "description": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", + "id", + "cycleName", + "duration", + "durationUnit", + "description" + ], + "example": "deleted" + }, + "uniqueItems": true + } + ], + "title": "billing_cycles.Fields" + } + }, + "additionalProperties": false, + "x-typescript-type": "@loopback/repository#Filter" + }, + "billing_cycles.Filter1": { + "type": "object", + "title": "billing_cycles.Filter", + "properties": { + "offset": { + "type": "integer", + "minimum": 0 }, - "id": { - "type": "string" + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 }, - "cycleName": { - "type": "string" + "skip": { + "type": "integer", + "minimum": 0 }, - "duration": { - "type": "number" + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] }, - "durationUnit": { - "type": "string" + "where": { + "title": "billing_cycles.WhereFilter", + "type": "object", + "additionalProperties": true }, - "description": { - "type": "string" + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, + "id": { + "type": "boolean" + }, + "cycleName": { + "type": "boolean" + }, + "duration": { + "type": "boolean" + }, + "durationUnit": { + "type": "boolean" + }, + "description": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", + "id", + "cycleName", + "duration", + "durationUnit", + "description" + ], + "example": "deleted" + }, + "uniqueItems": true + } + ], + "title": "billing_cycles.Fields" } }, - "required": ["cycleName", "duration", "durationUnit"], - "additionalProperties": false + "additionalProperties": false, + "x-typescript-type": "@loopback/repository#Filter" }, - "NewBillingCycle": { - "title": "NewBillingCycle", + "currencies.Filter": { "type": "object", - "description": "(tsType: Omit, schemaOptions: { title: 'NewBillingCycle', exclude: [ 'id' ] })", + "title": "currencies.Filter", "properties": { - "deleted": { - "type": "boolean" - }, - "deletedOn": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "deletedBy": { - "type": "string", - "nullable": true - }, - "createdOn": { - "type": "string", - "format": "date-time" - }, - "modifiedOn": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "string" - }, - "modifiedBy": { - "type": "string" + "offset": { + "type": "integer", + "minimum": 0 }, - "cycleName": { - "type": "string" + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 }, - "duration": { - "type": "number" + "skip": { + "type": "integer", + "minimum": 0 }, - "durationUnit": { - "type": "string" + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] }, - "description": { - "type": "string" + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "boolean" + }, + "currencyCode": { + "type": "boolean" + }, + "currencyName": { + "type": "boolean" + }, + "symbol": { + "type": "boolean" + }, + "country": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "id", + "currencyCode", + "currencyName", + "symbol", + "country" + ], + "example": "id" + }, + "uniqueItems": true + } + ], + "title": "currencies.Fields" } }, - "required": ["cycleName", "duration", "durationUnit"], "additionalProperties": false, - "x-typescript-type": "Omit" + "x-typescript-type": "@loopback/repository#Filter" }, - "BillingCyclePartial": { - "title": "BillingCyclePartial", + "currencies.Filter1": { "type": "object", - "description": "(tsType: Partial, schemaOptions: { partial: true })", + "title": "currencies.Filter", "properties": { - "deleted": { - "type": "boolean" - }, - "deletedOn": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "deletedBy": { - "type": "string", - "nullable": true - }, - "createdOn": { - "type": "string", - "format": "date-time" - }, - "modifiedOn": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "string" - }, - "modifiedBy": { - "type": "string" + "offset": { + "type": "integer", + "minimum": 0 }, - "id": { - "type": "string" + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 }, - "cycleName": { - "type": "string" + "skip": { + "type": "integer", + "minimum": 0 }, - "duration": { - "type": "number" + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] }, - "durationUnit": { - "type": "string" + "where": { + "title": "currencies.WhereFilter", + "type": "object", + "additionalProperties": true }, - "description": { - "type": "string" + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "boolean" + }, + "currencyCode": { + "type": "boolean" + }, + "currencyName": { + "type": "boolean" + }, + "symbol": { + "type": "boolean" + }, + "country": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "id", + "currencyCode", + "currencyName", + "symbol", + "country" + ], + "example": "id" + }, + "uniqueItems": true + } + ], + "title": "currencies.Fields" } }, "additionalProperties": false, - "x-typescript-type": "Partial" - }, - "loopback.Count": { - "type": "object", - "title": "loopback.Count", - "x-typescript-type": "@loopback/repository#Count", - "properties": { - "count": { - "type": "number" - } - } + "x-typescript-type": "@loopback/repository#Filter" }, - "billing_cycles.Filter": { + "feature_values.Filter": { "type": "object", - "title": "billing_cycles.Filter", + "title": "feature_values.Filter", "properties": { "offset": { "type": "integer", @@ -3679,16 +5823,19 @@ "id": { "type": "boolean" }, - "cycleName": { + "featureKey": { + "type": "boolean" + }, + "strategyKey": { "type": "boolean" }, - "duration": { + "strategyEntityId": { "type": "boolean" }, - "durationUnit": { + "status": { "type": "boolean" }, - "description": { + "value": { "type": "boolean" } }, @@ -3707,25 +5854,26 @@ "createdBy", "modifiedBy", "id", - "cycleName", - "duration", - "durationUnit", - "description" + "featureKey", + "strategyKey", + "strategyEntityId", + "status", + "value" ], "example": "deleted" }, "uniqueItems": true } ], - "title": "billing_cycles.Fields" + "title": "feature_values.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, - "billing_cycles.Filter1": { + "feature_values.Filter1": { "type": "object", - "title": "billing_cycles.Filter", + "title": "feature_values.Filter", "properties": { "offset": { "type": "integer", @@ -3754,7 +5902,7 @@ ] }, "where": { - "title": "billing_cycles.WhereFilter", + "title": "feature_values.WhereFilter", "type": "object", "additionalProperties": true }, @@ -3787,16 +5935,19 @@ "id": { "type": "boolean" }, - "cycleName": { + "featureKey": { "type": "boolean" }, - "duration": { + "strategyKey": { "type": "boolean" }, - "durationUnit": { + "strategyEntityId": { "type": "boolean" }, - "description": { + "status": { + "type": "boolean" + }, + "value": { "type": "boolean" } }, @@ -3815,25 +5966,26 @@ "createdBy", "modifiedBy", "id", - "cycleName", - "duration", - "durationUnit", - "description" + "featureKey", + "strategyKey", + "strategyEntityId", + "status", + "value" ], "example": "deleted" }, "uniqueItems": true } ], - "title": "billing_cycles.Fields" + "title": "feature_values.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, - "currencies.Filter": { + "features.Filter": { "type": "object", - "title": "currencies.Filter", + "title": "features.Filter", "properties": { "offset": { "type": "integer", @@ -3866,19 +6018,46 @@ { "type": "object", "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, "id": { "type": "boolean" }, - "currencyCode": { + "name": { "type": "boolean" }, - "currencyName": { + "key": { "type": "boolean" }, - "symbol": { + "description": { "type": "boolean" }, - "country": { + "defaultValue": { + "type": "boolean" + }, + "type": { + "type": "boolean" + }, + "metadata": { "type": "boolean" } }, @@ -3889,26 +6068,35 @@ "items": { "type": "string", "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", "id", - "currencyCode", - "currencyName", - "symbol", - "country" + "name", + "key", + "description", + "defaultValue", + "type", + "metadata" ], - "example": "id" + "example": "deleted" }, "uniqueItems": true } ], - "title": "currencies.Fields" + "title": "features.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, - "currencies.Filter1": { + "features.Filter1": { "type": "object", - "title": "currencies.Filter", + "title": "features.Filter", "properties": { "offset": { "type": "integer", @@ -3937,7 +6125,7 @@ ] }, "where": { - "title": "currencies.WhereFilter", + "title": "features.WhereFilter", "type": "object", "additionalProperties": true }, @@ -3946,19 +6134,46 @@ { "type": "object", "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, "id": { "type": "boolean" }, - "currencyCode": { + "name": { "type": "boolean" }, - "currencyName": { + "key": { "type": "boolean" }, - "symbol": { + "description": { "type": "boolean" }, - "country": { + "defaultValue": { + "type": "boolean" + }, + "type": { + "type": "boolean" + }, + "metadata": { "type": "boolean" } }, @@ -3969,22 +6184,31 @@ "items": { "type": "string", "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", "id", - "currencyCode", - "currencyName", - "symbol", - "country" + "name", + "key", + "description", + "defaultValue", + "type", + "metadata" ], - "example": "id" + "example": "deleted" }, "uniqueItems": true } ], - "title": "currencies.Fields" + "title": "features.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, "PingResponse": { "type": "object", @@ -4010,83 +6234,9 @@ } } }, - "plan_items.ScopeFilter": { - "type": "object", - "properties": { - "offset": { - "type": "integer", - "minimum": 0 - }, - "limit": { - "type": "integer", - "minimum": 1, - "example": 100 - }, - "skip": { - "type": "integer", - "minimum": 0 - }, - "order": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "where": { - "type": "object", - "additionalProperties": true - }, - "fields": { - "oneOf": [ - { - "type": "object", - "properties": {}, - "additionalProperties": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "uniqueItems": true - } - ] - }, - "include": { - "type": "array", - "items": { - "type": "object", - "properties": {}, - "additionalProperties": true - } - } - }, - "additionalProperties": false, - "title": "plan_items.ScopeFilter" - }, - "plan_items.IncludeFilter.Items": { - "title": "plan_items.IncludeFilter.Items", - "type": "object", - "properties": { - "relation": { - "type": "string", - "enum": ["plan"] - }, - "scope": { - "$ref": "#/components/schemas/plan_items.ScopeFilter" - } - } - }, - "plan_items.Filter": { + "plan_sizes.Filter": { "type": "object", - "title": "plan_items.Filter", + "title": "plan_sizes.Filter", "properties": { "offset": { "type": "integer", @@ -4119,40 +6269,13 @@ { "type": "object", "properties": { - "deleted": { - "type": "boolean" - }, - "deletedOn": { - "type": "boolean" - }, - "deletedBy": { - "type": "boolean" - }, - "createdOn": { - "type": "boolean" - }, - "modifiedOn": { - "type": "boolean" - }, - "createdBy": { - "type": "boolean" - }, - "modifiedBy": { - "type": "boolean" - }, "id": { "type": "boolean" }, - "name": { - "type": "boolean" - }, - "planItemType": { + "size": { "type": "boolean" }, - "value": { - "type": "boolean" - }, - "planId": { + "config": { "type": "boolean" } }, @@ -4163,47 +6286,24 @@ "items": { "type": "string", "enum": [ - "deleted", - "deletedOn", - "deletedBy", - "createdOn", - "modifiedOn", - "createdBy", - "modifiedBy", "id", - "name", - "planItemType", - "value", - "planId" + "size", + "config" ], - "example": "deleted" - }, - "uniqueItems": true - } - ], - "title": "plan_items.Fields" - }, - "include": { - "title": "plan_items.IncludeFilter", - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/plan_items.IncludeFilter.Items" - }, - { - "type": "string" - } - ] - } + "example": "id" + }, + "uniqueItems": true + } + ], + "title": "plan_sizes.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, - "plan_items.Filter1": { + "plan_sizes.Filter1": { "type": "object", - "title": "plan_items.Filter", + "title": "plan_sizes.Filter", "properties": { "offset": { "type": "integer", @@ -4232,7 +6332,7 @@ ] }, "where": { - "title": "plan_items.WhereFilter", + "title": "plan_sizes.WhereFilter", "type": "object", "additionalProperties": true }, @@ -4241,40 +6341,13 @@ { "type": "object", "properties": { - "deleted": { - "type": "boolean" - }, - "deletedOn": { - "type": "boolean" - }, - "deletedBy": { - "type": "boolean" - }, - "createdOn": { - "type": "boolean" - }, - "modifiedOn": { - "type": "boolean" - }, - "createdBy": { - "type": "boolean" - }, - "modifiedBy": { - "type": "boolean" - }, "id": { "type": "boolean" }, - "name": { - "type": "boolean" - }, - "planItemType": { - "type": "boolean" - }, - "value": { + "size": { "type": "boolean" }, - "planId": { + "config": { "type": "boolean" } }, @@ -4285,43 +6358,20 @@ "items": { "type": "string", "enum": [ - "deleted", - "deletedOn", - "deletedBy", - "createdOn", - "modifiedOn", - "createdBy", - "modifiedBy", "id", - "name", - "planItemType", - "value", - "planId" + "size", + "config" ], - "example": "deleted" + "example": "id" }, "uniqueItems": true } ], - "title": "plan_items.Fields" - }, - "include": { - "title": "plan_items.IncludeFilter", - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/plan_items.IncludeFilter.Items" - }, - { - "type": "string" - } - ] - } + "title": "plan_sizes.Fields" } }, "additionalProperties": false, - "x-typescript-type": "@loopback/repository#Filter" + "x-typescript-type": "@loopback/repository#Filter" }, "plans.ScopeFilter": { "type": "object", @@ -4390,7 +6440,10 @@ "properties": { "relation": { "type": "string", - "enum": ["planItems", "billingCycle", "currency"] + "enum": [ + "billingCycle", + "currency" + ] }, "scope": { "$ref": "#/components/schemas/plans.ScopeFilter" @@ -5042,6 +7095,209 @@ "additionalProperties": false, "x-typescript-type": "@loopback/repository#Filter" }, + "strategies.Filter": { + "type": "object", + "title": "strategies.Filter", + "properties": { + "offset": { + "type": "integer", + "minimum": 0 + }, + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 + }, + "skip": { + "type": "integer", + "minimum": 0 + }, + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, + "id": { + "type": "boolean" + }, + "name": { + "type": "boolean" + }, + "key": { + "type": "boolean" + }, + "priority": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", + "id", + "name", + "key", + "priority" + ], + "example": "deleted" + }, + "uniqueItems": true + } + ], + "title": "strategies.Fields" + } + }, + "additionalProperties": false, + "x-typescript-type": "@loopback/repository#Filter" + }, + "strategies.Filter1": { + "type": "object", + "title": "strategies.Filter", + "properties": { + "offset": { + "type": "integer", + "minimum": 0 + }, + "limit": { + "type": "integer", + "minimum": 1, + "example": 100 + }, + "skip": { + "type": "integer", + "minimum": 0 + }, + "order": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "where": { + "title": "strategies.WhereFilter", + "type": "object", + "additionalProperties": true + }, + "fields": { + "oneOf": [ + { + "type": "object", + "properties": { + "deleted": { + "type": "boolean" + }, + "deletedOn": { + "type": "boolean" + }, + "deletedBy": { + "type": "boolean" + }, + "createdOn": { + "type": "boolean" + }, + "modifiedOn": { + "type": "boolean" + }, + "createdBy": { + "type": "boolean" + }, + "modifiedBy": { + "type": "boolean" + }, + "id": { + "type": "boolean" + }, + "name": { + "type": "boolean" + }, + "key": { + "type": "boolean" + }, + "priority": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "deleted", + "deletedOn", + "deletedBy", + "createdOn", + "modifiedOn", + "createdBy", + "modifiedBy", + "id", + "name", + "key", + "priority" + ], + "example": "deleted" + }, + "uniqueItems": true + } + ], + "title": "strategies.Fields" + } + }, + "additionalProperties": false, + "x-typescript-type": "@loopback/repository#Filter" + }, "subscriptions.ScopeFilter": { "type": "object", "properties": { @@ -5109,7 +7365,9 @@ "properties": { "relation": { "type": "string", - "enum": ["plan"] + "enum": [ + "plan" + ] }, "scope": { "$ref": "#/components/schemas/subscriptions.ScopeFilter" @@ -5146,6 +7404,11 @@ } ] }, + "where": { + "title": "subscriptions.WhereFilter", + "type": "object", + "additionalProperties": true + }, "fields": { "oneOf": [ { @@ -5267,11 +7530,6 @@ } ] }, - "where": { - "title": "subscriptions.WhereFilter", - "type": "object", - "additionalProperties": true - }, "fields": { "oneOf": [ { @@ -5370,4 +7628,4 @@ "url": "/" } ] -} +} \ No newline at end of file diff --git a/services/subscription-service/src/permissions.ts b/services/subscription-service/src/permissions.ts index 6b75b20..d1b5c60 100644 --- a/services/subscription-service/src/permissions.ts +++ b/services/subscription-service/src/permissions.ts @@ -7,10 +7,6 @@ export const PermissionKey = { UpdatePlan: '7006', DeletePlan: '7007', ViewPlan: '7008', - CreatePlanItem: '7009', - UpdatePlanItem: '7010', - DeletePlanItem: '7011', - ViewPlanItem: '7012', CreateResource: '7013', UpdateResource: '7014', DeleteResource: '7015', @@ -27,6 +23,13 @@ export const PermissionKey = { UpdateCurrency: '7026', DeleteCurrency: '7027', ViewCurrency: '7028', + ViewPlanSizes: '7029', + CreatePlanSizes: '7030', + UpdatePlanSizes: '7031', + DeletePlanSizes: '7032', + ViewPlanFeatures: '7033', + AddPlanFeatures: '7034', + UpdatePlanFeatures: '7035', CreateLead: '10200', UpdateLead: '10201', DeleteLead: '10202', diff --git a/services/subscription-service/src/repositories/index.ts b/services/subscription-service/src/repositories/index.ts index 504174c..6a82b38 100644 --- a/services/subscription-service/src/repositories/index.ts +++ b/services/subscription-service/src/repositories/index.ts @@ -1,7 +1,7 @@ -export * from './plan-item.repository'; export * from './plan.repository'; export * from './resource.repository'; export * from './service.repository'; export * from './subscription.repository'; export * from './billing-cycle.repository'; export * from './currency.repository'; +export * from './plan-sizes.repository'; diff --git a/services/subscription-service/src/repositories/plan-item.repository.ts b/services/subscription-service/src/repositories/plan-item.repository.ts deleted file mode 100644 index 7e2083f..0000000 --- a/services/subscription-service/src/repositories/plan-item.repository.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {Getter, inject} from '@loopback/core'; -import {PlanItem, PlanItemRelations, Plan} from '../models'; -import { - DefaultUserModifyCrudRepository, - IAuthUserWithPermissions, -} from '@sourceloop/core'; -import {AuthenticationBindings} from 'loopback4-authentication'; -import {repository, BelongsToAccessor, juggler} from '@loopback/repository'; -import {PlanRepository} from './plan.repository'; -import {SubscriptionDbSourceName} from '../types'; - -export class PlanItemRepository extends DefaultUserModifyCrudRepository< - PlanItem, - typeof PlanItem.prototype.id, - PlanItemRelations -> { - public readonly plan: BelongsToAccessor; - - constructor( - @inject(`datasources.${SubscriptionDbSourceName}`) - dataSource: juggler.DataSource, - @inject.getter(AuthenticationBindings.CURRENT_USER) - public readonly getCurrentUser: Getter, - @repository.getter('PlanRepository') - protected planRepositoryGetter: Getter, - ) { - super(PlanItem, dataSource, getCurrentUser); - this.plan = this.createBelongsToAccessorFor('plan', planRepositoryGetter); - this.registerInclusionResolver('plan', this.plan.inclusionResolver); - } -} diff --git a/services/subscription-service/src/repositories/plan-sizes.repository.ts b/services/subscription-service/src/repositories/plan-sizes.repository.ts new file mode 100644 index 0000000..399a4a0 --- /dev/null +++ b/services/subscription-service/src/repositories/plan-sizes.repository.ts @@ -0,0 +1,24 @@ +import {Getter, inject} from '@loopback/core'; +import {PlanSizes, PlanSizesRelations} from '../models'; +import { + DefaultUserModifyCrudRepository, + IAuthUserWithPermissions, +} from '@sourceloop/core'; +import {AuthenticationBindings} from 'loopback4-authentication'; +import {juggler} from '@loopback/repository'; +import {SubscriptionDbSourceName} from '../types'; + +export class PlanSizesRepository extends DefaultUserModifyCrudRepository< + PlanSizes, + typeof PlanSizes.prototype.id, + PlanSizesRelations +> { + constructor( + @inject(`datasources.${SubscriptionDbSourceName}`) + dataSource: juggler.DataSource, + @inject.getter(AuthenticationBindings.CURRENT_USER) + public readonly getCurrentUser: Getter, + ) { + super(PlanSizes, dataSource, getCurrentUser); + } +} diff --git a/services/subscription-service/src/repositories/plan.repository.ts b/services/subscription-service/src/repositories/plan.repository.ts index 27e1651..9480d82 100644 --- a/services/subscription-service/src/repositories/plan.repository.ts +++ b/services/subscription-service/src/repositories/plan.repository.ts @@ -1,17 +1,11 @@ import {Getter, inject} from '@loopback/core'; -import {Plan, PlanRelations, PlanItem, BillingCycle, Currency} from '../models'; +import {Plan, PlanRelations, BillingCycle, Currency} from '../models'; import { DefaultUserModifyCrudRepository, IAuthUserWithPermissions, } from '@sourceloop/core'; import {AuthenticationBindings} from 'loopback4-authentication'; -import { - repository, - HasManyRepositoryFactory, - BelongsToAccessor, - juggler, -} from '@loopback/repository'; -import {PlanItemRepository} from './plan-item.repository'; +import {repository, BelongsToAccessor, juggler} from '@loopback/repository'; import {BillingCycleRepository} from './billing-cycle.repository'; import {CurrencyRepository} from './currency.repository'; import {SubscriptionDbSourceName} from '../types'; @@ -21,11 +15,6 @@ export class PlanRepository extends DefaultUserModifyCrudRepository< typeof Plan.prototype.id, PlanRelations > { - public readonly planItems: HasManyRepositoryFactory< - PlanItem, - typeof Plan.prototype.id - >; - public readonly billingCycle: BelongsToAccessor< BillingCycle, typeof Plan.prototype.id @@ -41,8 +30,6 @@ export class PlanRepository extends DefaultUserModifyCrudRepository< dataSource: juggler.DataSource, @inject.getter(AuthenticationBindings.CURRENT_USER) public readonly getCurrentUser: Getter, - @repository.getter('PlanItemRepository') - protected planItemRepositoryGetter: Getter, @repository.getter('BillingCycleRepository') protected billingCycleRepositoryGetter: Getter, @repository.getter('CurrencyRepository') @@ -62,14 +49,5 @@ export class PlanRepository extends DefaultUserModifyCrudRepository< this.billingCycle.inclusionResolver, ); this.registerInclusionResolver('currency', this.currency.inclusionResolver); - - this.planItems = this.createHasManyRepositoryFactoryFor( - 'planItems', - planItemRepositoryGetter, - ); - this.registerInclusionResolver( - 'planItems', - this.planItems.inclusionResolver, - ); } } diff --git a/services/tenant-management-service/src/__tests__/acceptance/mock-data.ts b/services/tenant-management-service/src/__tests__/acceptance/mock-data.ts index 54e8266..73d83cf 100644 --- a/services/tenant-management-service/src/__tests__/acceptance/mock-data.ts +++ b/services/tenant-management-service/src/__tests__/acceptance/mock-data.ts @@ -1,10 +1,5 @@ import {AnyObject, DataObject, DeepPartial} from '@loopback/repository'; -import { - InvoiceStatus, - NotificationType, - PlanTier, - TenantStatus, -} from '../../enums'; +import {InvoiceStatus, NotificationType, TenantStatus} from '../../enums'; import { Address, Contact, @@ -96,8 +91,7 @@ export const mockSubscriptionId = 'test-subscription-id'; export const mockSusbcription: DeepPartial = { id: '1', plan: { - tier: PlanTier.POOLED, - planItems: [], + tier: 'Standard', }, }; diff --git a/services/tenant-management-service/src/enums/index.ts b/services/tenant-management-service/src/enums/index.ts index 2d931b6..3b6659c 100644 --- a/services/tenant-management-service/src/enums/index.ts +++ b/services/tenant-management-service/src/enums/index.ts @@ -3,4 +3,3 @@ export * from './invoice-status.enum'; export * from './webhook-types.enum'; export * from './subscription-status.enum'; export * from './notification-type.enum'; -export * from './plans-tier.enum'; diff --git a/services/tenant-management-service/src/enums/plans-tier.enum.ts b/services/tenant-management-service/src/enums/plans-tier.enum.ts deleted file mode 100644 index acc3154..0000000 --- a/services/tenant-management-service/src/enums/plans-tier.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum PlanTier { - POOLED, - SILO, -} diff --git a/services/tenant-management-service/src/models/dtos/plan-item-dto.model.ts b/services/tenant-management-service/src/models/dtos/plan-item-dto.model.ts deleted file mode 100644 index b1a3620..0000000 --- a/services/tenant-management-service/src/models/dtos/plan-item-dto.model.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {Model, model, property} from '@loopback/repository'; -import {IPlanItem, IValue} from '../../types'; - -@model({ - description: 'model describing plan items', -}) -export class PlanItemDTO extends Model implements IPlanItem { - @property({ - type: 'string', - id: true, - generated: true, - }) - id: string; - - @property({ - type: 'string', - required: true, - description: 'name of the plan item', - }) - name: string; - - @property({ - type: 'string', - required: true, - name: 'plan_item_type', - description: 'type of the plan item', - }) - planItemType: string; - - @property({ - type: 'object', - required: true, - description: 'value of the plan item', - }) - value: IValue; - - constructor(data?: Partial) { - super(data); - } -} diff --git a/services/tenant-management-service/src/types/i-subscription.interface.ts b/services/tenant-management-service/src/types/i-subscription.interface.ts index ce0f6f1..5e0debe 100644 --- a/services/tenant-management-service/src/types/i-subscription.interface.ts +++ b/services/tenant-management-service/src/types/i-subscription.interface.ts @@ -1,5 +1,5 @@ +import {AnyObject} from '@loopback/repository'; import {IServiceConfig} from '@sourceloop/core'; -import {PlanTier} from '../enums'; export interface ISubscription { deleted?: boolean; @@ -88,9 +88,10 @@ export interface IPlan { price: number; currencyId: string; metaData: IMetaData; - tier: PlanTier; + tier: string; + size?: string; + sizeConfig?: AnyObject; billingCycleId: string; - planItems?: IPlanItem[]; billingCycle?: IBillingCycle; currency?: ICurrency; } @@ -98,23 +99,3 @@ export interface IPlan { export interface IMetaData { pipelineName: string; } - -export interface IPlanItem { - deleted?: boolean; - deletedOn?: string; - deletedBy?: string; - createdOn?: string; - modifiedOn?: string; - createdBy?: string; - modifiedBy?: string; - id: string; - name: string; - planItemType: string; - value: IValue; - planId?: string; -} - -export interface IValue { - name: string; - value: number | string | boolean; -} diff --git a/services/tenant-management-service/src/types/index.ts b/services/tenant-management-service/src/types/index.ts index ac6487e..9cea043 100644 --- a/services/tenant-management-service/src/types/index.ts +++ b/services/tenant-management-service/src/types/index.ts @@ -37,3 +37,4 @@ export * from './webhook-payload.type'; export * from './resource.type'; export * from './i-provisioning-service.interface'; export * from './i-subscription.interface'; +export * from './i-event-connector.interface';