anicove / api /models /notifications.py
mwask's picture
Upload 403 files
72b125b verified
Raw History Blame Contribute Delete
2.32 kB
"""In-app notifications for the mobile client."""
from datetime import datetime, timezone
from bson import ObjectId
from pymongo import DESCENDING
from ..core.db_connector import notifications_collection
def _ensure_indexes():
try:
notifications_collection.create_index(
[("user_id", 1), ("created_at", DESCENDING)]
)
notifications_collection.create_index([("user_id", 1), ("is_read", 1)])
except Exception:
pass
_ensure_indexes()
def _serialize(doc, user_id=None):
if not doc:
return None
read_by = [str(u) for u in doc.get("read_by", [])]
uid = str(user_id) if user_id is not None else ""
created = doc.get("created_at")
return {
"id": str(doc["_id"]),
"title": doc.get("title") or "",
"message": doc.get("message") or "",
"type": doc.get("type") or "info",
"created_at": created.isoformat() if created else datetime.now(timezone.utc).isoformat(),
"is_read": uid in read_by if uid else bool(doc.get("is_read")),
}
def list_notifications(user_id, limit=50):
uid = str(user_id)
cursor = notifications_collection.find(
{"$or": [{"user_id": uid}, {"user_id": {"$exists": False}}, {"broadcast": True}]}
).sort("created_at", DESCENDING).limit(limit)
return [_serialize(doc, uid) for doc in cursor]
def mark_read(user_id, notification_id):
uid = str(user_id)
try:
oid = ObjectId(notification_id)
except Exception:
return False
result = notifications_collection.update_one(
{"_id": oid},
{"$addToSet": {"read_by": uid}, "$set": {"is_read": True}},
)
return result.matched_count > 0
def mark_all_read(user_id):
uid = str(user_id)
notifications_collection.update_many(
{"$or": [{"user_id": uid}, {"broadcast": True}]},
{"$addToSet": {"read_by": uid}},
)
return True
def delete_notification(user_id, notification_id):
uid = str(user_id)
try:
oid = ObjectId(notification_id)
except Exception:
return False
result = notifications_collection.delete_one(
{"_id": oid, "$or": [{"user_id": uid}, {"broadcast": True}]}
)
return result.deleted_count > 0