SplitTest.js 3.0 KB

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