File size: 1,519 Bytes
78664f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import "server-only";

import mongoose, { Schema, type Model } from "mongoose";

export const EVENT_TYPES = [
  "request.received",
  "request.accepted",
  "request.rejected",
  "invite.received",
  "invite.responded",
  "request.withdrawn",
  "team.updated",
  "team.disbanded",
  "member.left",
  "member.removed",
  "leadership.transferred",
  "message.received",
] as const;

export type EventType = (typeof EVENT_TYPES)[number];

export interface NotificationDoc {
  _id: mongoose.Types.ObjectId;
  userId: string;
  type: EventType;
  data: Record<string, unknown>;
  readAt: Date | null;
  eventId: string;
  createdAt: Date;
  updatedAt: Date;
}

const NotificationSchema = new Schema<NotificationDoc>(
  {
    userId: { type: String, required: true, index: true },
    type: { type: String, enum: EVENT_TYPES, required: true },
    data: { type: Schema.Types.Mixed, default: () => ({}) },
    readAt: { type: Date, default: null, index: true },
    eventId: { type: String, required: true, unique: true },
  },
  {
    timestamps: true,
  }
);

// TTL index: auto-delete notifications after 30 days
NotificationSchema.index({ createdAt: 1 }, { expireAfterSeconds: 30 * 24 * 60 * 60 });
// Compound index for fast queries: user's unread / chronological list
NotificationSchema.index({ userId: 1, readAt: 1, createdAt: -1 });

export const Notification: Model<NotificationDoc> =
  (mongoose.models.Notification as Model<NotificationDoc>) ||
  mongoose.model<NotificationDoc>("Notification", NotificationSchema);