in-app-notification.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import type { Types, Document, Model } from 'mongoose';
  2. import { Schema } from 'mongoose';
  3. import mongoosePaginate from 'mongoose-paginate-v2';
  4. import { AllSupportedTargetModels, AllSupportedActions } from '~/interfaces/activity';
  5. import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
  6. import { getOrCreateModel } from '../util/mongoose-utils';
  7. import type { ActivityDocument } from './activity';
  8. const { STATUS_UNOPENED, STATUS_OPENED } = InAppNotificationStatuses;
  9. export interface InAppNotificationDocument extends Document {
  10. _id: Types.ObjectId
  11. user: Types.ObjectId
  12. targetModel: string
  13. target: Types.ObjectId
  14. action: string
  15. activities: ActivityDocument[]
  16. status: string
  17. createdAt: Date
  18. snapshot: string
  19. }
  20. export interface InAppNotificationModel extends Model<InAppNotificationDocument> {
  21. findLatestInAppNotificationsByUser(user: Types.ObjectId, skip: number, offset: number)
  22. getUnreadCountByUser(user: Types.ObjectId): Promise<number | undefined>
  23. open(user, id: Types.ObjectId): Promise<InAppNotificationDocument | null>
  24. read(user) /* : Promise<Query<any>> */
  25. STATUS_UNOPENED: string
  26. STATUS_OPENED: string
  27. }
  28. const inAppNotificationSchema = new Schema<InAppNotificationDocument, InAppNotificationModel>({
  29. user: {
  30. type: Schema.Types.ObjectId,
  31. ref: 'User',
  32. index: true,
  33. required: true,
  34. },
  35. targetModel: {
  36. type: String,
  37. required: true,
  38. enum: AllSupportedTargetModels,
  39. },
  40. target: {
  41. type: Schema.Types.ObjectId,
  42. refPath: 'targetModel',
  43. required: true,
  44. },
  45. action: {
  46. type: String,
  47. required: true,
  48. enum: AllSupportedActions,
  49. },
  50. activities: [
  51. {
  52. type: Schema.Types.ObjectId,
  53. ref: 'Activity',
  54. },
  55. ],
  56. status: {
  57. type: String,
  58. default: STATUS_UNOPENED,
  59. enum: InAppNotificationStatuses,
  60. index: true,
  61. required: true,
  62. },
  63. snapshot: {
  64. type: String,
  65. required: true,
  66. },
  67. }, {
  68. timestamps: { createdAt: true, updatedAt: false },
  69. });
  70. // indexes
  71. inAppNotificationSchema.index({ createdAt: 1 });
  72. // apply plugins
  73. inAppNotificationSchema.plugin(mongoosePaginate);
  74. const transform = (doc, ret) => {
  75. delete ret.activities;
  76. };
  77. inAppNotificationSchema.set('toObject', { virtuals: true, transform });
  78. inAppNotificationSchema.set('toJSON', { virtuals: true, transform });
  79. inAppNotificationSchema.index({
  80. user: 1, target: 1, action: 1, createdAt: 1,
  81. });
  82. inAppNotificationSchema.statics.STATUS_UNOPENED = function() {
  83. return STATUS_UNOPENED;
  84. };
  85. inAppNotificationSchema.statics.STATUS_OPENED = function() {
  86. return STATUS_OPENED;
  87. };
  88. const InAppNotification = getOrCreateModel<InAppNotificationDocument, InAppNotificationModel>('InAppNotification', inAppNotificationSchema);
  89. export { InAppNotification };