mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
add server to monorepo.
This commit is contained in:
30
packages/server/src/system/models/Invite.ts
Normal file
30
packages/server/src/system/models/Invite.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
import moment from 'moment';
|
||||
|
||||
export default class UserInvite extends SystemModel {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'user_invites';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Model modifiers.
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
notExpired(query) {
|
||||
const comp = moment().subtract(24, 'hours').toMySqlDateTime();
|
||||
query.where('created_at', '>=', comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
packages/server/src/system/models/PasswordReset.ts
Normal file
17
packages/server/src/system/models/PasswordReset.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
|
||||
export default class PasswordResets extends SystemModel {
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'password_resets';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt'];
|
||||
}
|
||||
}
|
||||
129
packages/server/src/system/models/Subscriptions/License.ts
Normal file
129
packages/server/src/system/models/Subscriptions/License.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import moment from 'moment';
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
|
||||
export default class License extends SystemModel {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'subscription_licenses';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Model modifiers.
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
// Filters active licenses.
|
||||
filterActiveLicense(query) {
|
||||
query.where('disabled_at', null);
|
||||
query.where('used_at', null);
|
||||
},
|
||||
|
||||
// Find license by its code or id.
|
||||
findByCodeOrId(query, id, code) {
|
||||
if (id) {
|
||||
query.where('id', id);
|
||||
}
|
||||
if (code) {
|
||||
query.where('license_code', code);
|
||||
}
|
||||
},
|
||||
|
||||
// Filters licenses list.
|
||||
filter(builder, licensesFilter) {
|
||||
if (licensesFilter.active) {
|
||||
builder.modify('filterActiveLicense');
|
||||
}
|
||||
if (licensesFilter.disabled) {
|
||||
builder.whereNot('disabled_at', null);
|
||||
}
|
||||
if (licensesFilter.used) {
|
||||
builder.whereNot('used_at', null);
|
||||
}
|
||||
if (licensesFilter.sent) {
|
||||
builder.whereNot('sent_at', null);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Plan = require('system/models/Subscriptions/Plan');
|
||||
|
||||
return {
|
||||
plan: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Plan.default,
|
||||
join: {
|
||||
from: 'subscription_licenses.planId',
|
||||
to: 'subscriptions_plans.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given license code from the storage.
|
||||
* @param {string} licenseCode
|
||||
* @return {Promise}
|
||||
*/
|
||||
static deleteLicense(licenseCode, viaAttribute = 'license_code') {
|
||||
return this.query().where(viaAttribute, licenseCode).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given license code as disabled on the storage.
|
||||
* @param {string} licenseCode
|
||||
* @return {Promise}
|
||||
*/
|
||||
static markLicenseAsDisabled(licenseCode, viaAttribute = 'license_code') {
|
||||
return this.query().where(viaAttribute, licenseCode).patch({
|
||||
disabled_at: moment().toMySqlDateTime(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given license code as sent on the storage.
|
||||
* @param {string} licenseCode
|
||||
*/
|
||||
static markLicenseAsSent(licenseCode, viaAttribute = 'license_code') {
|
||||
return this.query().where(viaAttribute, licenseCode).patch({
|
||||
sent_at: moment().toMySqlDateTime(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given license code as used on the storage.
|
||||
* @param {string} licenseCode
|
||||
* @return {Promise}
|
||||
*/
|
||||
static markLicenseAsUsed(licenseCode, viaAttribute = 'license_code') {
|
||||
return this.query().where(viaAttribute, licenseCode).patch({
|
||||
used_at: moment().toMySqlDateTime(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {IIPlan} plan
|
||||
* @return {boolean}
|
||||
*/
|
||||
isEqualPlanPeriod(plan) {
|
||||
return (
|
||||
this.invoicePeriod === plan.invoiceInterval &&
|
||||
license.licensePeriod === license.periodInterval
|
||||
);
|
||||
}
|
||||
}
|
||||
82
packages/server/src/system/models/Subscriptions/Plan.ts
Normal file
82
packages/server/src/system/models/Subscriptions/Plan.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
import { PlanSubscription } from '..';
|
||||
|
||||
export default class Plan extends mixin(SystemModel) {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'subscription_plans';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['isFree', 'hasTrial'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Model modifiers.
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
getFeatureBySlug(builder, featureSlug) {
|
||||
builder.where('slug', featureSlug);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const PlanSubscription = require('system/models/Subscriptions/PlanSubscription');
|
||||
|
||||
return {
|
||||
/**
|
||||
* The plan may have many subscriptions.
|
||||
*/
|
||||
subscriptions: {
|
||||
relation: Model.HasManyRelation,
|
||||
modelClass: PlanSubscription.default,
|
||||
join: {
|
||||
from: 'subscription_plans.id',
|
||||
to: 'subscription_plan_subscriptions.planId',
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plan is free.
|
||||
* @return {boolean}
|
||||
*/
|
||||
isFree() {
|
||||
return this.price <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plan is paid.
|
||||
* @return {boolean}
|
||||
*/
|
||||
isPaid() {
|
||||
return !this.isFree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plan has trial.
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasTrial() {
|
||||
return this.trialPeriod && this.trialInterval;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
|
||||
export default class PlanFeature extends mixin(SystemModel) {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'subscriptions.plan_features';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
static get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Plan = require('system/models/Subscriptions/Plan');
|
||||
|
||||
return {
|
||||
plan: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Plan.default,
|
||||
join: {
|
||||
from: 'subscriptions.plan_features.planId',
|
||||
to: 'subscriptions.plans.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
import moment from 'moment';
|
||||
import SubscriptionPeriod from '@/services/Subscription/SubscriptionPeriod';
|
||||
|
||||
export default class PlanSubscription extends mixin(SystemModel) {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'subscription_plan_subscriptions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['active', 'inactive', 'ended', 'onTrial'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifiers queries.
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
activeSubscriptions(builder) {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const now = moment().format(dateFormat);
|
||||
|
||||
builder.where('ends_at', '>', now);
|
||||
builder.where('trial_ends_at', '>', now);
|
||||
},
|
||||
|
||||
inactiveSubscriptions() {
|
||||
builder.modify('endedTrial');
|
||||
builder.modify('endedPeriod');
|
||||
},
|
||||
|
||||
subscriptionBySlug(builder, subscriptionSlug) {
|
||||
builder.where('slug', subscriptionSlug);
|
||||
},
|
||||
|
||||
endedTrial(builder) {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const endDate = moment().format(dateFormat);
|
||||
|
||||
builder.where('ends_at', '<=', endDate);
|
||||
},
|
||||
|
||||
endedPeriod(builder) {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const endDate = moment().format(dateFormat);
|
||||
|
||||
builder.where('trial_ends_at', '<=', endDate);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Relations mappings.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Tenant = require('system/models/Tenant');
|
||||
const Plan = require('system/models/Subscriptions/Plan');
|
||||
|
||||
return {
|
||||
/**
|
||||
* Plan subscription belongs to tenant.
|
||||
*/
|
||||
tenant: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Tenant.default,
|
||||
join: {
|
||||
from: 'subscription_plan_subscriptions.tenantId',
|
||||
to: 'tenants.id',
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Plan description belongs to plan.
|
||||
*/
|
||||
plan: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Plan.default,
|
||||
join: {
|
||||
from: 'subscription_plan_subscriptions.planId',
|
||||
to: 'subscription_plans.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is active.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
active() {
|
||||
return !this.ended() || this.onTrial();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is inactive.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
inactive() {
|
||||
return !this.active();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription period has ended.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
ended() {
|
||||
return this.endsAt ? moment().isAfter(this.endsAt) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is currently on trial.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
onTrial() {
|
||||
return this.trailEndsAt ? moment().isAfter(this.trailEndsAt) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new period from the given details.
|
||||
* @param {string} invoiceInterval
|
||||
* @param {number} invoicePeriod
|
||||
* @param {string} start
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
static setNewPeriod(invoiceInterval, invoicePeriod, start) {
|
||||
const period = new SubscriptionPeriod(
|
||||
invoiceInterval,
|
||||
invoicePeriod,
|
||||
start,
|
||||
);
|
||||
|
||||
const startsAt = period.getStartDate();
|
||||
const endsAt = period.getEndDate();
|
||||
|
||||
return { startsAt, endsAt };
|
||||
}
|
||||
|
||||
/**
|
||||
* Renews subscription period.
|
||||
* @Promise
|
||||
*/
|
||||
renew(invoiceInterval, invoicePeriod) {
|
||||
const { startsAt, endsAt } = PlanSubscription.setNewPeriod(
|
||||
invoiceInterval,
|
||||
invoicePeriod,
|
||||
);
|
||||
return this.$query().update({ startsAt, endsAt });
|
||||
}
|
||||
}
|
||||
19
packages/server/src/system/models/SystemModel.ts
Normal file
19
packages/server/src/system/models/SystemModel.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Container } from 'typedi';
|
||||
import BaseModel from 'models/Model';
|
||||
|
||||
export default class SystemModel extends BaseModel{
|
||||
/**
|
||||
* Loging all system database queries.
|
||||
* @param {...any} args
|
||||
*/
|
||||
static query(...args) {
|
||||
const Logger = Container.get('logger');
|
||||
return super.query(...args).onBuildKnex(knexQueryBuilder => {
|
||||
knexQueryBuilder.on('query', queryData => {
|
||||
Logger.info(`[query][system] ${queryData.sql}`, {
|
||||
bindings: queryData.bindings,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
85
packages/server/src/system/models/SystemUser.ts
Normal file
85
packages/server/src/system/models/SystemUser.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { Model } from 'objection';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import SystemModel from '@/system/models/SystemModel';
|
||||
import SoftDeleteQueryBuilder from '@/collection/SoftDeleteQueryBuilder';
|
||||
|
||||
export default class SystemUser extends SystemModel {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'users';
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft delete query builder.
|
||||
*/
|
||||
static get QueryBuilder() {
|
||||
return SoftDeleteQueryBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['fullName', 'isDeleted', 'isInviteAccepted'];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get isDeleted() {
|
||||
return !!this.deletedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get isInviteAccepted() {
|
||||
return !!this.inviteAcceptedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full name attribute.
|
||||
*/
|
||||
get fullName() {
|
||||
return (this.firstName + ' ' + this.lastName).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Tenant = require('system/models/Tenant');
|
||||
|
||||
return {
|
||||
/**
|
||||
* System user may belongs to tenant model.
|
||||
*/
|
||||
tenant: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Tenant.default,
|
||||
join: {
|
||||
from: 'users.tenantId',
|
||||
to: 'tenants.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the password of the user.
|
||||
* @param {String} password - The given password.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
verifyPassword(password) {
|
||||
return bcrypt.compareSync(password, this.password);
|
||||
}
|
||||
}
|
||||
226
packages/server/src/system/models/Tenant.ts
Normal file
226
packages/server/src/system/models/Tenant.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
import moment from 'moment';
|
||||
import { Model } from 'objection';
|
||||
import uniqid from 'uniqid';
|
||||
import SubscriptionPeriod from '@/services/Subscription/SubscriptionPeriod';
|
||||
import BaseModel from 'models/Model';
|
||||
import TenantMetadata from './TenantMetadata';
|
||||
import PlanSubscription from './Subscriptions/PlanSubscription';
|
||||
|
||||
export default class Tenant extends BaseModel {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'tenants';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['isReady', 'isBuildRunning', 'isUpgradeRunning'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tenant is ready.
|
||||
*/
|
||||
get isReady() {
|
||||
return !!(this.initializedAt && this.seededAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarimes the tenant whether is build currently running.
|
||||
*/
|
||||
get isBuildRunning() {
|
||||
return !!this.buildJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmines the tenant whether is upgrade currently running.
|
||||
*/
|
||||
get isUpgradeRunning() {
|
||||
return !!this.upgradeJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query modifiers.
|
||||
*/
|
||||
static modifiers() {
|
||||
return {
|
||||
subscriptions(builder) {
|
||||
builder.withGraphFetched('subscriptions');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Relations mappings.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const PlanSubscription = require('./Subscriptions/PlanSubscription');
|
||||
const TenantMetadata = require('./TenantMetadata');
|
||||
|
||||
return {
|
||||
subscriptions: {
|
||||
relation: Model.HasManyRelation,
|
||||
modelClass: PlanSubscription.default,
|
||||
join: {
|
||||
from: 'tenants.id',
|
||||
to: 'subscription_plan_subscriptions.tenantId',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
relation: Model.HasOneRelation,
|
||||
modelClass: TenantMetadata.default,
|
||||
join: {
|
||||
from: 'tenants.id',
|
||||
to: 'tenants_metadata.tenantId',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the subscribed plans ids.
|
||||
* @return {number[]}
|
||||
*/
|
||||
async subscribedPlansIds() {
|
||||
const { subscriptions } = this;
|
||||
return chain(subscriptions).map('planId').unq();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} planId
|
||||
* @param {*} invoiceInterval
|
||||
* @param {*} invoicePeriod
|
||||
* @param {*} subscriptionSlug
|
||||
* @returns
|
||||
*/
|
||||
newSubscription(planId, invoiceInterval, invoicePeriod, subscriptionSlug) {
|
||||
return Tenant.newSubscription(
|
||||
this.id,
|
||||
planId,
|
||||
invoiceInterval,
|
||||
invoicePeriod,
|
||||
subscriptionSlug,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a new subscription for the associated tenant.
|
||||
*/
|
||||
static newSubscription(
|
||||
tenantId,
|
||||
planId,
|
||||
invoiceInterval,
|
||||
invoicePeriod,
|
||||
subscriptionSlug
|
||||
) {
|
||||
const period = new SubscriptionPeriod(invoiceInterval, invoicePeriod);
|
||||
|
||||
return PlanSubscription.query().insert({
|
||||
tenantId,
|
||||
slug: subscriptionSlug,
|
||||
planId,
|
||||
startsAt: period.getStartDate(),
|
||||
endsAt: period.getEndDate(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tenant with random organization id.
|
||||
*/
|
||||
static createWithUniqueOrgId(uniqId) {
|
||||
const organizationId = uniqid() || uniqId;
|
||||
return this.query().insert({ organizationId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark as seeded.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
static markAsSeeded(tenantId) {
|
||||
const seededAt = moment().toMySqlDateTime();
|
||||
return this.query().update({ seededAt }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the the given organization as initialized.
|
||||
* @param {string} organizationId
|
||||
*/
|
||||
static markAsInitialized(tenantId) {
|
||||
const initializedAt = moment().toMySqlDateTime();
|
||||
return this.query().update({ initializedAt }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given tenant as built.
|
||||
*/
|
||||
static markAsBuilt(tenantId) {
|
||||
const builtAt = moment().toMySqlDateTime();
|
||||
return this.query().update({ builtAt }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given tenant as built.
|
||||
*/
|
||||
static markAsBuilding(tenantId, buildJobId) {
|
||||
return this.query().update({ buildJobId }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given tenant as built.
|
||||
*/
|
||||
static markAsBuildCompleted(tenantId) {
|
||||
return this.query().update({ buildJobId: null }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given tenant as upgrading.
|
||||
* @param {number} tenantId
|
||||
* @param {string} upgradeJobId
|
||||
* @returns
|
||||
*/
|
||||
static markAsUpgrading(tenantId, upgradeJobId) {
|
||||
return this.query().update({ upgradeJobId }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Markes the given tenant as upgraded.
|
||||
* @param {number} tenantId
|
||||
* @returns
|
||||
*/
|
||||
static markAsUpgraded(tenantId) {
|
||||
return this.query().update({ upgradeJobId: null }).where({ id: tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the metadata of the given tenant.
|
||||
*/
|
||||
static async saveMetadata(tenantId, metadata) {
|
||||
const foundMetadata = await TenantMetadata.query().findOne({ tenantId });
|
||||
const updateOrInsert = foundMetadata ? 'update' : 'insert';
|
||||
|
||||
return TenantMetadata.query()
|
||||
[updateOrInsert]({
|
||||
tenantId,
|
||||
...metadata,
|
||||
})
|
||||
.where({ tenantId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the metadata of the tenant.
|
||||
*/
|
||||
saveMetadata(metadata) {
|
||||
return Tenant.saveMetadata(this.id, metadata);
|
||||
}
|
||||
}
|
||||
10
packages/server/src/system/models/TenantMetadata.ts
Normal file
10
packages/server/src/system/models/TenantMetadata.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import BaseModel from 'models/Model';
|
||||
|
||||
export default class TenantMetadata extends BaseModel {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'tenants_metadata';
|
||||
}
|
||||
}
|
||||
22
packages/server/src/system/models/index.ts
Normal file
22
packages/server/src/system/models/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
import Plan from './Subscriptions/Plan';
|
||||
import PlanFeature from './Subscriptions/PlanFeature';
|
||||
import PlanSubscription from './Subscriptions/PlanSubscription';
|
||||
import License from './Subscriptions/License';
|
||||
import Tenant from './Tenant';
|
||||
import TenantMetadata from './TenantMetadata';
|
||||
import SystemUser from './SystemUser';
|
||||
import PasswordReset from './PasswordReset';
|
||||
import Invite from './Invite';
|
||||
|
||||
export {
|
||||
Plan,
|
||||
PlanFeature,
|
||||
PlanSubscription,
|
||||
License,
|
||||
Tenant,
|
||||
TenantMetadata,
|
||||
SystemUser,
|
||||
PasswordReset,
|
||||
Invite,
|
||||
}
|
||||
Reference in New Issue
Block a user