subscription.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. getSubscriptions(targets: Types.ObjectId[]): Promise<Types.ObjectId[]>
  24. }
  25. const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
  26. user: {
  27. type: Schema.Types.ObjectId,
  28. ref: 'User',
  29. index: true,
  30. required: true,
  31. },
  32. targetModel: {
  33. type: String,
  34. require: true,
  35. enum: AllSupportedTargetModelType,
  36. },
  37. target: {
  38. type: Schema.Types.ObjectId,
  39. refPath: 'targetModel',
  40. require: true,
  41. },
  42. status: {
  43. type: String,
  44. require: true,
  45. enum: AllSubscriptionStatusType,
  46. },
  47. }, {
  48. timestamps: true,
  49. });
  50. subscriptionSchema.methods.isSubscribing = function() {
  51. return this.status === SubscriptionStatusType.SUBSCRIBE;
  52. };
  53. subscriptionSchema.methods.isUnsubscribing = function() {
  54. return this.status === SubscriptionStatusType.UNSUBSCRIBE;
  55. };
  56. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  57. return this.findOne({ user: userId, target: targetId });
  58. };
  59. subscriptionSchema.statics.upsertSubscription = function(user, targetModel, target, status) {
  60. const query = { user, targetModel, target };
  61. const doc = { ...query, status };
  62. const options = {
  63. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  64. };
  65. return this.findOneAndUpdate(query, doc, options);
  66. };
  67. subscriptionSchema.statics.subscribeByPageId = function(user, pageId, status) {
  68. return this.upsertSubscription(user, 'Page', pageId, status);
  69. };
  70. subscriptionSchema.statics.getSubscription = async function(target) {
  71. return this.find({ target, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  72. };
  73. subscriptionSchema.statics.getUnsubscription = async function(target) {
  74. return this.find({ target, status: SubscriptionStatusType.UNSUBSCRIBE }).distinct('user');
  75. };
  76. subscriptionSchema.statics.getSubscriptions = async function(targets) {
  77. return this.find({ $in: targets, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  78. };
  79. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);