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);
|