SplitTest.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. const mongoose = require('../infrastructure/Mongoose')
  2. const { Schema } = mongoose
  3. const { ObjectId } = Schema
  4. const MIN_NAME_LENGTH = 3
  5. const MAX_NAME_LENGTH = 200
  6. const MIN_VARIANT_NAME_LENGTH = 3
  7. const MAX_VARIANT_NAME_LENGTH = 255
  8. const NAME_REGEX = /^[a-z0-9-]+$/
  9. const RolloutPercentType = {
  10. type: Number,
  11. default: 0,
  12. min: [0, 'Rollout percentage must be between 0 and 100, got {VALUE}'],
  13. max: [100, 'Rollout percentage must be between 0 and 100, got {VALUE}'],
  14. required: true,
  15. }
  16. const BadgeSchema = new Schema(
  17. {
  18. tooltipText: {
  19. type: String,
  20. required: false,
  21. },
  22. url: {
  23. type: String,
  24. required: false,
  25. },
  26. },
  27. { _id: false }
  28. )
  29. const BadgeInfoSchema = new Schema(
  30. {
  31. alpha: BadgeSchema,
  32. beta: BadgeSchema,
  33. release: BadgeSchema,
  34. },
  35. { _id: false }
  36. )
  37. const VariantSchema = new Schema(
  38. {
  39. name: {
  40. type: String,
  41. minLength: MIN_VARIANT_NAME_LENGTH,
  42. maxLength: MAX_VARIANT_NAME_LENGTH,
  43. required: true,
  44. validate: {
  45. validator: function (input) {
  46. return input !== null && input !== 'default' && NAME_REGEX.test(input)
  47. },
  48. message: `invalid, cannot be 'default' and must match: ${NAME_REGEX}, got {VALUE}`,
  49. },
  50. },
  51. rolloutPercent: RolloutPercentType,
  52. rolloutStripes: [
  53. {
  54. start: RolloutPercentType,
  55. end: RolloutPercentType,
  56. },
  57. ],
  58. },
  59. { _id: false }
  60. )
  61. const VersionSchema = new Schema(
  62. {
  63. versionNumber: {
  64. type: Number,
  65. default: 1,
  66. min: [1, 'must be 1 or higher, got {VALUE}'],
  67. required: true,
  68. },
  69. phase: {
  70. type: String,
  71. default: 'alpha',
  72. enum: ['alpha', 'beta', 'release'],
  73. required: true,
  74. },
  75. active: {
  76. type: Boolean,
  77. default: true,
  78. required: true,
  79. },
  80. analyticsEnabled: {
  81. type: Boolean,
  82. default: true,
  83. required: true,
  84. },
  85. variants: [VariantSchema],
  86. createdAt: {
  87. type: Date,
  88. default: Date.now,
  89. },
  90. author: { type: ObjectId, ref: 'User' },
  91. comment: {
  92. type: String,
  93. required: false,
  94. },
  95. },
  96. { _id: false }
  97. )
  98. const SplitTestSchema = new Schema(
  99. {
  100. name: {
  101. type: String,
  102. minLength: MIN_NAME_LENGTH,
  103. maxlength: MAX_NAME_LENGTH,
  104. required: true,
  105. unique: true,
  106. validate: {
  107. validator: function (input) {
  108. return input !== null && NAME_REGEX.test(input)
  109. },
  110. message: `invalid, must match: ${NAME_REGEX}`,
  111. },
  112. },
  113. versions: [VersionSchema],
  114. forbidReleasePhase: {
  115. type: Boolean,
  116. required: false,
  117. },
  118. description: {
  119. type: String,
  120. required: false,
  121. },
  122. expectedEndDate: {
  123. type: Date,
  124. required: false,
  125. },
  126. requiredCohortSize: {
  127. type: Number,
  128. required: false,
  129. },
  130. expectedUplift: {
  131. type: Number,
  132. required: false,
  133. },
  134. ticketUrl: {
  135. type: String,
  136. required: false,
  137. },
  138. reportsUrls: {
  139. type: [String],
  140. required: false,
  141. default: [],
  142. },
  143. winningVariant: {
  144. type: String,
  145. required: false,
  146. },
  147. archived: {
  148. type: Boolean,
  149. required: false,
  150. },
  151. archivedAt: {
  152. type: Date,
  153. required: false,
  154. },
  155. archivedBy: { type: ObjectId, ref: 'User' },
  156. badgeInfo: {
  157. type: BadgeInfoSchema,
  158. required: false,
  159. },
  160. },
  161. { minimize: false }
  162. )
  163. module.exports = {
  164. SplitTest: mongoose.model('SplitTest', SplitTestSchema),
  165. SplitTestSchema,
  166. }