in-app-notification.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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_UNREAD, 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_UNREAD: string
  26. STATUS_UNOPENED: string
  27. STATUS_OPENED: string
  28. }
  29. const inAppNotificationSchema = new Schema<InAppNotificationDocument, InAppNotificationModel>({
  30. user: {
  31. type: Schema.Types.ObjectId,
  32. ref: 'User',
  33. index: true,
  34. required: true,
  35. },
  36. targetModel: {
  37. type: String,
  38. required: true,
  39. enum: AllSupportedTargetModels,
  40. },
  41. target: {
  42. type: Schema.Types.ObjectId,
  43. refPath: 'targetModel',
  44. required: true,
  45. },
  46. action: {
  47. type: String,
  48. required: true,
  49. enum: AllSupportedActions,
  50. },
  51. activities: [
  52. {
  53. type: Schema.Types.ObjectId,
  54. ref: 'Activity',
  55. },
  56. ],
  57. status: {
  58. type: String,
  59. default: STATUS_UNREAD,
  60. enum: InAppNotificationStatuses,
  61. index: true,
  62. required: true,
  63. },
  64. snapshot: {
  65. type: String,
  66. required: true,
  67. },
  68. }, {
  69. timestamps: { createdAt: true, updatedAt: false },
  70. });
  71. // indexes
  72. inAppNotificationSchema.index({ createdAt: 1 });
  73. // apply plugins
  74. inAppNotificationSchema.plugin(mongoosePaginate);
  75. const transform = (doc, ret) => {
  76. delete ret.activities;
  77. };
  78. inAppNotificationSchema.set('toObject', { virtuals: true, transform });
  79. inAppNotificationSchema.set('toJSON', { virtuals: true, transform });
  80. inAppNotificationSchema.index({
  81. user: 1, target: 1, action: 1, createdAt: 1,
  82. });
  83. inAppNotificationSchema.statics.STATUS_UNOPENED = function() {
  84. return STATUS_UNOPENED;
  85. };
  86. inAppNotificationSchema.statics.STATUS_UNREAD = function() {
  87. return STATUS_UNREAD;
  88. };
  89. inAppNotificationSchema.statics.STATUS_OPENED = function() {
  90. return STATUS_OPENED;
  91. };
  92. const InAppNotification = getOrCreateModel<InAppNotificationDocument, InAppNotificationModel>('InAppNotification', inAppNotificationSchema);
  93. export { InAppNotification };