import mongoose from '../infrastructure/Mongoose.mjs' import { TeamInviteSchema } from './TeamInvite.mjs' import { callbackify } from '@overleaf/promise-utils' const { Schema } = mongoose const { ObjectId } = Schema const PaymentProvider = { service: { type: String, }, subscriptionId: { type: String, }, state: { type: String, }, pausePeriodStart: { type: Date, }, pausePeriodEnd: { type: Date, }, trialStartedAt: { type: Date, }, trialEndsAt: { type: Date, }, } export const SubscriptionSchema = new Schema( { admin_id: { type: ObjectId, ref: 'User', index: { unique: true, dropDups: true }, }, manager_ids: { type: [ObjectId], ref: 'User', required: true, validate: function (managers) { // require at least one manager return !!managers.length }, }, member_ids: [{ type: ObjectId, ref: 'User' }], groupPolicy: { type: ObjectId, ref: 'GroupPolicy' }, invited_emails: [String], teamInvites: [TeamInviteSchema], recurlySubscription_id: String, teamName: { type: String }, teamNotice: { type: String }, planCode: { type: String }, groupPlan: { type: Boolean, default: false }, domainCaptureEnabled: { type: Boolean, default: false }, managedUsersEnabled: { type: Boolean, default: false }, membersLimit: { type: Number, default: 0 }, membersLimitNotificationSent: { type: Boolean, default: false }, customAccount: Boolean, features: { managedUsers: { type: Boolean, default: true }, groupSSO: { type: Boolean, default: true }, domainCapture: { type: Boolean, default: false }, }, userFeaturesDisabled: Boolean, addOns: Schema.Types.Mixed, overleaf: { id: { type: Number, index: { unique: true, partialFilterExpression: { 'overleaf.id': { $exists: true } }, }, }, }, recurlyStatus: { state: { type: String, }, trialStartedAt: { type: Date, }, trialEndsAt: { type: Date, }, }, paymentProvider: PaymentProvider, previousPaymentProvider: PaymentProvider, collectionMethod: { type: String, enum: ['automatic', 'manual'], default: 'automatic', }, v1_id: { type: Number, required: false, min: 1, }, salesforce_id: { type: String, required: false, validate: { validator: function (salesforceId) { return ( salesforceId == null || salesforceId === '' || salesforceId.match(/^(?:[A-Za-z0-9]{15}|[A-Za-z0-9]{18})$/) ) }, }, }, ssoConfig: { type: ObjectId, ref: 'SSOConfig' }, sharingPermissions: { byEmail: { type: String, enum: ['anyone_in_x', 'anyone'], default: 'anyone', }, byLinkSharing: { type: String, enum: ['no_one', 'anyone_in_x', 'anyone'], default: 'anyone', }, }, }, { minimize: false } ) // Subscriptions have no v1 data to fetch async function fetchV1DataPromise() { return this } SubscriptionSchema.method('fetchV1Data', callbackify(fetchV1DataPromise)) SubscriptionSchema.method('fetchV1DataPromise', fetchV1DataPromise) export const Subscription = mongoose.model('Subscription', SubscriptionSchema)