function notify_document_update
Sends notifications to interested users (owners, department members, subscribers, and users with permissions) when a controlled document is created, updated, or has a status/version change.
/tf/active/vicechatdev/CDocs/utils/notifications.py
1459 - 1570
complex
Purpose
This function orchestrates the notification process for document lifecycle events in a document management system. It queries a Neo4j graph database to identify all users who should be notified about document changes based on ownership, department membership, explicit subscriptions, or document permissions. It then creates appropriate notification messages and sends them via the system's notification service, including email notifications with customized templates.
Source Code
def notify_document_update(document, notification_type: str) -> List[str]:
"""
Send document update notifications to interested users.
Args:
document: ControlledDocument instance
notification_type: Type of notification
Returns:
List of created notification UIDs
"""
try:
# Find users who should be notified of document updates
# This might include document owner, department users, etc.
query = """
MATCH (d:ControlledDocument {UID: $doc_uid})
// Document owner
OPTIONAL MATCH (u1:User {UID: d.ownerUID})
// Department users
OPTIONAL MATCH (u2:User)-[:HAS_ROLE]->(:Role)-[:FOR_DEPARTMENT]->(dept:Department {Code: d.department})
// Users with explicit document subscriptions
OPTIONAL MATCH (u3:User)-[:SUBSCRIBED_TO]->(d)
// Users with permission to this document
OPTIONAL MATCH (u4:User)-[:HAS_PERMISSION]->(:Permission)-[:FOR_DOCUMENT]->(d)
RETURN collect(distinct u1) + collect(distinct u2) + collect(distinct u3) + collect(distinct u4) as users
"""
result = db.run_query(query, {"doc_uid": document.uid})
if not result or 'users' not in result[0]:
logger.warning(f"No users to notify for document {document.uid}")
return []
users = result[0]['users']
user_uids = [user['UID'] for user in users if user and 'UID' in user]
if not user_uids:
logger.warning(f"No users to notify for document {document.uid}")
return []
# Get current version if available
current_version = document.current_version
version_number = current_version.version_number if current_version else "N/A"
# Prepare notification details
details = {
'doc_uid': document.uid,
'doc_number': document.doc_number,
'doc_type': document.doc_type,
'title': document.title,
'status': document.status,
'version_number': version_number
}
# Create message based on notification type
message = None
if notification_type == 'DOCUMENT_CREATED':
message = f"New document created: {document.doc_number} - {document.title}"
elif notification_type == 'DOCUMENT_UPDATED':
message = f"Document updated: {document.doc_number} - {document.title}"
elif notification_type == 'DOCUMENT_STATUS_CHANGED':
message = f"Document status changed to {document.status}: {document.doc_number} - {document.title}"
elif notification_type == 'VERSION_CREATED':
message = f"New version created: {document.doc_number} (v{version_number}) - {document.title}"
# Determine email template based on notification type
email_template = None
if notification_type == 'DOCUMENT_CREATED':
email_template = 'document_created'
elif notification_type == 'DOCUMENT_UPDATED':
email_template = 'document_updated'
elif notification_type == 'DOCUMENT_STATUS_CHANGED':
email_template = 'document_status_changed'
elif notification_type == 'VERSION_CREATED':
email_template = 'version_created'
# Send notification
return send_notification(
notification_type=notification_type,
users=user_uids,
resource_uid=document.uid,
resource_type='ControlledDocument',
message=message,
details=details,
send_email=True,
email_template=email_template,
email_data={
"app_url": settings.APP_URL,
"doc_uid": document.uid,
"doc_number": document.doc_number,
"title": document.title,
"version_number": document.current_version.version_number if document.current_version else "N/A",
"department": document.department,
"doc_type": document.doc_type,
"status": document.status,
"document_url": f"{settings.APP_URL}/document/{document.uid}",
"cdocs_app_url": "https://cdocs.vicebio.com",
"cdocs_app_text": "Access the CDocs Application",
"current_year": datetime.now().strftime("%Y"),
"app_name": settings.APP_NAME,
"sender_name": settings.EMAIL_SENDER_NAME
}
)
except Exception as e:
logger.error(f"Error sending document update notification: {e}")
return []
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
document |
- | - | positional_or_keyword |
notification_type |
str | - | positional_or_keyword |
Parameter Details
document: A ControlledDocument instance representing the document that triggered the notification. Must have attributes: uid, doc_number, doc_type, title, status, department, and optionally current_version with version_number.
notification_type: String indicating the type of notification event. Expected values: 'DOCUMENT_CREATED', 'DOCUMENT_UPDATED', 'DOCUMENT_STATUS_CHANGED', or 'VERSION_CREATED'. This determines the notification message and email template used.
Return Value
Type: List[str]
Returns a List[str] containing UIDs of successfully created notifications. Returns an empty list if no users need to be notified or if an error occurs during the notification process.
Dependencies
loggingtypingdatetimeCDocs.dbCDocs.config.settingsCDocs.models.user_extensions.DocUserCDocs.utils.audit_trailCDocs.controllers.document_controllermodels.review.ReviewCyclemodels.approval.Approval
Required Imports
from typing import List
from datetime import datetime
from CDocs import db
from CDocs.config import settings
import logging
Usage Example
from typing import List
from datetime import datetime
from CDocs import db
from CDocs.config import settings
import logging
# Assuming you have a ControlledDocument instance
from models.document import ControlledDocument
# Create or retrieve a document
document = ControlledDocument(
uid='doc-12345',
doc_number='DOC-001',
doc_type='SOP',
title='Standard Operating Procedure',
status='DRAFT',
department='QA',
ownerUID='user-001'
)
# Notify users when document is created
notification_uids = notify_document_update(
document=document,
notification_type='DOCUMENT_CREATED'
)
print(f"Created {len(notification_uids)} notifications")
# Notify users when document status changes
document.status = 'APPROVED'
notification_uids = notify_document_update(
document=document,
notification_type='DOCUMENT_STATUS_CHANGED'
)
# Notify users when new version is created
notification_uids = notify_document_update(
document=document,
notification_type='VERSION_CREATED'
)
Best Practices
- Ensure the document object has all required attributes (uid, doc_number, doc_type, title, status, department) before calling this function
- Use appropriate notification_type values from the predefined set: 'DOCUMENT_CREATED', 'DOCUMENT_UPDATED', 'DOCUMENT_STATUS_CHANGED', 'VERSION_CREATED'
- The function handles exceptions gracefully and returns an empty list on error, so check the return value to verify notifications were sent
- Ensure Neo4j database schema includes the expected relationships: HAS_ROLE, FOR_DEPARTMENT, SUBSCRIBED_TO, HAS_PERMISSION, FOR_DOCUMENT
- Configure email templates in your email service that match the template names used: 'document_created', 'document_updated', 'document_status_changed', 'version_created'
- The function deduplicates users automatically, so the same user won't receive multiple notifications for the same event
- Monitor logs for warnings about missing users or errors during notification sending
- Ensure the send_notification function is properly configured and available in the module scope
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function update_document 66.9% similar
-
function update_document_v1 65.3% similar
-
function send_notification 65.1% similar
-
function create_document 64.9% similar
-
function create_document_legacy 64.8% similar