subscription.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { getOrCreateModel } from '@growi/core';
  2. import {
  3. Types, Document, Model, Schema,
  4. } from 'mongoose';
  5. import { AllSupportedTargetModels } from '~/interfaces/activity';
  6. import { SubscriptionStatusType, AllSubscriptionStatusType } from '~/interfaces/subscription';
  7. export interface ISubscription {
  8. user: Types.ObjectId
  9. targetModel: string
  10. target: Types.ObjectId
  11. status: string
  12. createdAt: Date
  13. isSubscribing(): boolean
  14. isUnsubscribing(): boolean
  15. }
  16. export interface SubscriptionDocument extends ISubscription, Document {}
  17. export interface SubscriptionModel extends Model<SubscriptionDocument> {
  18. findByUserIdAndTargetId(userId: Types.ObjectId | string, targetId: Types.ObjectId | string): any
  19. upsertSubscription(user: Types.ObjectId, targetModel: string, target: Types.ObjectId, status: string): any
  20. subscribeByPageId(user: Types.ObjectId, pageId: Types.ObjectId, status: string): any
  21. getSubscription(target: Types.ObjectId): Promise<Types.ObjectId[]>
  22. getUnsubscription(target: Types.ObjectId): Promise<Types.ObjectId[]>
  23. }
  24. const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
  25. user: {
  26. type: Schema.Types.ObjectId,
  27. ref: 'User',
  28. index: true,
  29. required: true,
  30. },
  31. targetModel: {
  32. type: String,
  33. required: true,
  34. enum: AllSupportedTargetModels,
  35. },
  36. target: {
  37. type: Schema.Types.ObjectId,
  38. refPath: 'targetModel',
  39. required: true,
  40. },
  41. status: {
  42. type: String,
  43. required: true,
  44. enum: AllSubscriptionStatusType,
  45. },
  46. }, {
  47. timestamps: true,
  48. });
  49. subscriptionSchema.methods.isSubscribing = function() {
  50. return this.status === SubscriptionStatusType.SUBSCRIBE;
  51. };
  52. subscriptionSchema.methods.isUnsubscribing = function() {
  53. return this.status === SubscriptionStatusType.UNSUBSCRIBE;
  54. };
  55. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  56. return this.findOne({ user: userId, target: targetId });
  57. };
  58. subscriptionSchema.statics.upsertSubscription = function(user, targetModel, target, status) {
  59. const query = { user, targetModel, target };
  60. const doc = { ...query, status };
  61. const options = {
  62. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  63. };
  64. return this.findOneAndUpdate(query, doc, options);
  65. };
  66. subscriptionSchema.statics.subscribeByPageId = function(user, pageId, status) {
  67. return this.upsertSubscription(user, 'Page', pageId, status);
  68. };
  69. subscriptionSchema.statics.getSubscription = async function(target) {
  70. return this.find({ target, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  71. };
  72. subscriptionSchema.statics.getUnsubscription = async function(target) {
  73. return this.find({ target, status: SubscriptionStatusType.UNSUBSCRIBE }).distinct('user');
  74. };
  75. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);