🔍 Code Extractor

function update_document_v4

Maturity: 63

Updates metadata fields of a controlled document in a Neo4j database after validating user permissions and field constraints.

File:
/tf/active/vicechatdev/CDocs copy/controllers/document_controller.py
Lines:
1584 - 1695
Complexity:
moderate

Purpose

This function provides a secure way to update document metadata in a document management system. It retrieves an existing document by UID, validates that the user has EDIT_DOCUMENT permission, filters the update data to only allowed fields (title, description, department, owner_uid, doc_type, status), executes a Neo4j Cypher query to update the document properties, and creates an audit trail entry. The function handles permission checking with fallback logic for different permission system implementations and returns a structured response indicating success or failure.

Source Code

def update_document(document_uid: str, user: DocUser, data: Dict[str, Any]) -> Dict[str, Any]:
    """
    Update document metadata.
    
    Args:
        document_uid: UID of the document to update
        user: User making the update
        data: Dictionary of data to update
        
    Returns:
        Dictionary with update result
    """
    logger.info(f"Updating document {document_uid}")
    logger.debug(f"Update data: {data}")
    
    try:
        # Get current document
        document = get_document(document_uid)
        if not document:
            return {
                "success": False,
                "message": f"Document {document_uid} not found"
            }
        
        # Check permissions - fallback to normal permission check if resource method not available
        if hasattr(permissions, 'user_has_permission_for_resource'):
            has_permission = permissions.user_has_permission_for_resource(
                user, "EDIT_DOCUMENT", document
            )
        else:
            has_permission = permissions.user_has_permission(user, "EDIT_DOCUMENT")
            
        if not has_permission:
            return {
                "success": False,
                "message": "You don't have permission to edit this document"
            }
        
        # Validate allowed fields
        allowed_fields = [
            'title', 'description', 'department', 'owner_uid', 'doc_type', 'status'
        ]
        update_data = {k: v for k, v in data.items() if k in allowed_fields}
        
        # If empty update, return success
        if not update_data:
            return {
                "success": True,
                "message": "No fields to update",
                "document": document
            }
        
        # Build update query
        set_clauses = []
        params = {
            "document_uid": document_uid
        }
        
        for key, value in update_data.items():
            # Use Neo4j property names (camelCase)
            neo4j_key = key
            if key == 'doc_type':
                neo4j_key = 'docType'
                
            set_clauses.append(f"doc.{neo4j_key} = ${key}")
            params[key] = value
        
        # Add modified date
        from datetime import datetime
        modified_date = datetime.now().isoformat()
        set_clauses.append("doc.modifiedDate = $modified_date")
        params["modified_date"] = modified_date
        
        # Execute update
        query = f"""
        MATCH (doc:ControlledDocument)
        WHERE doc.UID = $document_uid
        SET {', '.join(set_clauses)}
        RETURN doc
        """
        
        result = db.run_query(query, params)
        
        if result and len(result) > 0:
            updated_document = result[0].get('doc')
            
            # Add audit trail entry
            create_audit_entry(
                user=user,
                document_uid=document_uid,
                action="UPDATE_METADATA",
                details=f"Updated fields: {', '.join(update_data.keys())}"
            )
            
            return {
                "success": True,
                "message": "Document updated successfully",
                "document": updated_document
            }
        else:
            return {
                "success": False,
                "message": "Failed to update document"
            }
    except Exception as e:
        logger.error(f"Error updating document {document_uid}: {e}")
        import traceback
        logger.error(traceback.format_exc())
        return {
            "success": False,
            "message": str(e)
        }

Parameters

Name Type Default Kind
document_uid str - positional_or_keyword
user DocUser - positional_or_keyword
data Dict[str, Any] - positional_or_keyword

Parameter Details

document_uid: Unique identifier (UID) string for the document to be updated. Must correspond to an existing document in the database with a matching UID property.

user: DocUser object representing the authenticated user making the update request. Used for permission checking and audit trail creation. Must have appropriate permissions to edit documents.

data: Dictionary containing the metadata fields to update. Keys should match allowed field names (title, description, department, owner_uid, doc_type, status). Only fields present in the allowed_fields list will be processed; other fields are silently ignored.

Return Value

Type: Dict[str, Any]

Returns a dictionary with keys: 'success' (boolean indicating if update succeeded), 'message' (string describing the result or error), and optionally 'document' (the updated document object from Neo4j if successful). On failure, only success and message keys are present. The document key contains the Neo4j node properties when the update succeeds.

Dependencies

  • logging
  • datetime
  • traceback
  • typing
  • CDocs.db
  • CDocs.config.permissions
  • CDocs.models.user_extensions
  • CDocs.utils.audit_trail

Required Imports

import logging
from typing import Dict, Any
from datetime import datetime
import traceback
from CDocs import db
from CDocs.config import permissions
from CDocs.models.user_extensions import DocUser

Conditional/Optional Imports

These imports are only needed under specific conditions:

from datetime import datetime

Condition: imported inside the function to set modified_date timestamp

Required (conditional)

Usage Example

from CDocs.models.user_extensions import DocUser
from typing import Dict, Any

# Assume user object is already authenticated
user = DocUser(uid='user123', username='john.doe')

# Prepare update data
update_data = {
    'title': 'Updated Document Title',
    'description': 'New description for the document',
    'status': 'DRAFT',
    'department': 'Engineering'
}

# Update the document
result = update_document(
    document_uid='doc-12345',
    user=user,
    data=update_data
)

# Check result
if result['success']:
    print(f"Document updated: {result['message']}")
    updated_doc = result.get('document')
else:
    print(f"Update failed: {result['message']}")

Best Practices

  • Always check the 'success' field in the returned dictionary before accessing the 'document' field
  • Only fields in the allowed_fields list (title, description, department, owner_uid, doc_type, status) will be updated; other fields are ignored
  • The function automatically adds a modifiedDate timestamp to track when updates occur
  • Permission checking has fallback logic - ensure your permissions module implements at least one of the expected methods
  • All updates are logged and create audit trail entries for compliance tracking
  • The function handles exceptions gracefully and returns error messages rather than raising exceptions
  • Field name 'doc_type' is automatically converted to camelCase 'docType' for Neo4j property naming conventions
  • Empty update data (no allowed fields) returns success without making database changes
  • Ensure the document_uid exists before calling this function or handle the 'Document not found' error case

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function update_document_v2 82.6% similar

    Updates properties of a controlled document including title, description, status, owner, and metadata with permission checks, validation, and audit tracking.

    From: /tf/active/vicechatdev/CDocs copy/controllers/document_controller.py
  • function update_document 78.1% similar

    Updates properties of a controlled document including title, description, status, owner, and metadata, with special handling for status transitions that require format conversions or publishing workflows.

    From: /tf/active/vicechatdev/document_controller_backup.py
  • function update_document_v1 77.8% similar

    Updates properties of a controlled document including title, description, status, owner, and metadata, with special handling for status transitions that require format conversions or publishing workflows.

    From: /tf/active/vicechatdev/CDocs single class/controllers/document_controller.py
  • function update_document_v3 77.1% similar

    Updates a controlled document's properties (title, description, status, owner, metadata) with validation, audit logging, and special handling for status transitions that require PDF publishing or training resets.

    From: /tf/active/vicechatdev/CDocs/controllers/document_controller.py
  • function update_document_metadata_in_filecloud 75.3% similar

    Updates metadata for a document stored in FileCloud, merging new metadata with existing values and logging the update in an audit trail.

    From: /tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
← Back to Browse