subscription.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { getOrCreateModel } from '@growi/core';
  2. import {
  3. Types, Document, Model, Schema,
  4. } from 'mongoose';
  5. import { AllSupportedTargetModelType } 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. require: true,
  34. enum: AllSupportedTargetModelType,
  35. },
  36. target: {
  37. type: Schema.Types.ObjectId,
  38. refPath: 'targetModel',
  39. require: true,
  40. },
  41. status: {
  42. type: String,
  43. require: true,
  44. enum: AllSubscriptionStatusType,
  45. },
  46. createdAt: { type: Date, default: new Date() },
  47. });
  48. subscriptionSchema.methods.isSubscribing = function() {
  49. return this.status === SubscriptionStatusType.SUBSCRIBE;
  50. };
  51. subscriptionSchema.methods.isUnsubscribing = function() {
  52. return this.status === SubscriptionStatusType.UNSUBSCRIBE;
  53. };
  54. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  55. return this.findOne({ user: userId, target: targetId });
  56. };
  57. subscriptionSchema.statics.upsertSubscription = function(user, targetModel, target, status) {
  58. const query = { user, targetModel, target };
  59. const doc = { ...query, status };
  60. const options = {
  61. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  62. };
  63. return this.findOneAndUpdate(query, doc, options);
  64. };
  65. subscriptionSchema.statics.subscribeByPageId = function(user, pageId, status) {
  66. return this.upsertSubscription(user, 'Page', pageId, status);
  67. };
  68. subscriptionSchema.statics.getSubscription = async function(target) {
  69. return this.find({ target, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  70. };
  71. subscriptionSchema.statics.getUnsubscription = async function(target) {
  72. return this.find({ target, status: SubscriptionStatusType.UNSUBSCRIBE }).distinct('user');
  73. };
  74. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);