Files
nick-doc/02 - Data Models/Notification.md
2026-05-23 20:35:34 +03:30

3.3 KiB

title, tags, aliases
title tags aliases
Notification
data-model
mongoose
User Notification
INotification

Notification

Per-user notification entry. Each row binds to one userId (stored as a string rather than ObjectId), carries a typed severity (info / success / warning / error) and a domain category, optionally references another entity via relatedId, and supports an actionUrl for deep-linking. Old notifications are auto-purged by a 90-day TTL index.

[!note] Source backend/src/models/Notification.ts:18 — schema definition backend/src/models/Notification.ts:79 — model export

[!warning] String userId userId is a String, not an ObjectId, and is not declared with ref. Consumers must cast to ObjectId if they want to populate() it as a User.

Schema

Field Type Required Default Validation Index Description
userId String yes yes (single + compound) Owner of the notification.
title String yes maxlength 200 Headline.
message String yes maxlength 1000 Body.
type String yes info enum: info / success / warning / error Severity.
category String yes enum: purchase_request / offer / payment / delivery / system yes (compound) Domain bucket.
relatedId String no yes Id of the related entity (e.g. PurchaseRequest).
metadata Mixed no Arbitrary payload.
actionUrl String no maxlength 500 Deep link.
isRead Boolean no false yes (compound) Read flag.
readAt Date no When read.
createdAt Date auto yes (compound + TTL) Mongoose timestamp.
updatedAt Date auto Mongoose timestamp.

The collection name is overridden to notifications via collection: 'notifications'.

Virtuals

None defined.

Indexes

Defined at backend/src/models/Notification.ts:71-77:

  • { userId: 1, createdAt: -1 } — user feed.
  • { userId: 1, isRead: 1 } — unread badge.
  • { userId: 1, category: 1 } — category filter.
  • { relatedId: 1 } — lookup by linked entity.
  • { createdAt: 1 } with expireAfterSeconds: 60 * 60 * 24 * 90 — auto-delete after 90 days.

Plus the implicit index from userId having index: true at the field level.

Pre/Post Hooks

None declared.

Instance Methods

None defined.

Static Methods

None defined.

Relationships

  • References: User indirectly through userId (string); arbitrary entity via relatedId.
  • Referenced by: none.

State Transitions

stateDiagram-v2
    [*] --> unread
    unread --> read : user opens
    read --> [*] : TTL purge (90d)
    unread --> [*] : TTL purge (90d)

Common Queries

// User feed
Notification.find({ userId }).sort({ createdAt: -1 }).limit(50);

// Unread badge count
Notification.countDocuments({ userId, isRead: false });

// Mark all read
Notification.updateMany(
  { userId, isRead: false },
  { $set: { isRead: true, readAt: new Date() } }
);

// All notifications about a request
Notification.find({ relatedId: purchaseRequestId.toString() });

Related: User, PurchaseRequest, SellerOffer, Payment.