function create_document_version_v1
Creates a new version of an existing document in a document management system, storing the file content in FileCloud and maintaining version history in Neo4j graph database.
/tf/active/vicechatdev/CDocs copy/controllers/document_controller.py
571 - 708
complex
Purpose
This function handles the complete workflow of document versioning in a controlled document management system. It validates document existence, generates incremental version numbers, creates version nodes in Neo4j, establishes relationships between documents and versions, updates document metadata, and creates audit trail entries. The function is designed for regulated environments requiring strict version control and traceability.
Source Code
def create_document_version(
user: DocUser,
document_uid: str,
file_content: bytes,
file_name: str,
comment: str = ""
) -> Dict[str, Any]:
"""
Create a new version of a document, storing file in FileCloud.
Args:
user: User creating the version
document_uid: UID of the document
file_content: Binary content of the file
file_name: Name of the file
comment: Comment for this version
Returns:
Dictionary with version information
"""
logger.info(f"Creating new version for document {document_uid}")
try:
# Check if document exists
document = get_document(document_uid)
if not document:
raise ResourceNotFoundError(f"Document {document_uid} not found")
# Extract file extension
file_ext = file_name.split('.')[-1].lower() if '.' in file_name else ''
# Process file content if needed (extract text, etc.)
extracted_text = ""
# try:
# # Use document processor to extract text if available
# extracted_text = document_processor.extract_text(file_content, file_ext)
# except Exception as proc_err:
# logger.warning(f"Could not extract text from document: {proc_err}")
# Generate next version number
current_revision = document.get('revision', '1.0')
try:
major, minor = current_revision.split('.')
next_revision = f"{major}.{int(minor) + 1}"
except (ValueError, AttributeError):
next_revision = "1.1" # Default if parsing fails
# Create version UID
version_uid = str(uuid.uuid4())
# Create version properties
version_properties = {
'UID': version_uid,
'created_by_uid': user.uid,
'created_by_name': user.username if hasattr(user, 'username') else 'Unknown',
'created_date': datetime.now().isoformat(),
'version_number': next_revision,
'file_name': file_name,
'file_size': len(file_content) if file_content else 0,
'file_type': file_ext,
'comment': comment,
#'text_content': extracted_text,
'storage_type': 'FILECLOUD' # Indicate storage type
}
# Add status
version_properties['status'] = 'ACTIVE'
# Create version node in Neo4j
version_node = db.create_node(
NodeLabels.DOCUMENT_VERSION,
version_properties
)
if not version_node:
logger.error("Failed to create version node")
return None
# Create relationship between document and version
relation_created = db.create_relationship(
document_uid,
version_uid,
RelTypes.HAS_VERSION
)
if not relation_created:
logger.error("Failed to create relationship between document and version")
return None
# Update document revision
doc_update_result = db.run_query(
"""
MATCH (d:ControlledDocument {UID: $doc_uid})
SET d.revision = $revision,
d.modifiedDate = $modified_date
RETURN d
""",
{
"doc_uid": document_uid,
"revision": next_revision,
"modified_date": datetime.now().isoformat()
}
)
# Set as current version if update successful
if doc_update_result:
current_version_set = db.run_query(
"""
MATCH (d:ControlledDocument {UID: $doc_uid})
SET d.currentVersionUID = $version_uid
RETURN d
""",
{
"doc_uid": document_uid,
"version_uid": version_uid
}
)
# Create audit trail entry
try:
create_audit_entry(
user=user,
document_uid=document_uid,
action="CREATE_VERSION",
details=f"Created version {next_revision}: {comment}"
)
except Exception as audit_err:
logger.warning(f"Error creating audit entry: {audit_err}")
# Return version properties
return version_properties
except Exception as e:
logger.error(f"Error creating document version: {e}")
import traceback
logger.error(traceback.format_exc())
raise BusinessRuleError(f"Failed to create document version: {e}")
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
DocUser | - | positional_or_keyword |
document_uid |
str | - | positional_or_keyword |
file_content |
bytes | - | positional_or_keyword |
file_name |
str | - | positional_or_keyword |
comment |
str | '' | positional_or_keyword |
Parameter Details
user: DocUser object representing the authenticated user creating the version. Must have CREATE_VERSION permission. Used for audit trail and version metadata.
document_uid: String UUID identifying the parent document. Must exist in the database or ResourceNotFoundError is raised.
file_content: Binary content (bytes) of the file being versioned. Used to calculate file size and potentially extract text content. Can be empty bytes.
file_name: String name of the file including extension. Used to extract file type and store as version metadata. Should include file extension (e.g., 'document.pdf').
comment: Optional string comment describing the changes in this version. Defaults to empty string. Stored in version metadata and audit trail.
Return Value
Type: Dict[str, Any]
Returns a dictionary containing version information with keys: 'UID' (version UUID), 'created_by_uid', 'created_by_name', 'created_date' (ISO format), 'version_number' (e.g., '1.2'), 'file_name', 'file_size' (bytes), 'file_type' (extension), 'comment', 'storage_type' ('FILECLOUD'), and 'status' ('ACTIVE'). Returns None if version node or relationship creation fails. Raises BusinessRuleError on exceptions.
Dependencies
logginguuiddatetimetypingtracebackCDocs.dbCDocs.configCDocs.models.user_extensionsCDocs.utils.audit_trailCDocs.db.schema_managerCDocs.controllers
Required Imports
import logging
import uuid
from datetime import datetime
from typing import Dict, Any
import traceback
from CDocs import db
from CDocs.models.user_extensions import DocUser
from CDocs.db.schema_manager import NodeLabels, RelTypes
from CDocs.controllers import log_controller_action, require_permission, transaction
from CDocs.controllers import ResourceNotFoundError, BusinessRuleError
Conditional/Optional Imports
These imports are only needed under specific conditions:
from CDocs.utils.audit_trail import create_audit_entry
Condition: Required for audit trail functionality, wrapped in try-except in code
Required (conditional)from CDocs.utils import document_processor
Condition: For text extraction from documents (currently commented out in code)
OptionalUsage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers.document_controller import create_document_version
# Assume user and document already exist
user = DocUser(uid='user-123', username='john.doe')
document_uid = 'doc-456'
# Read file content
with open('updated_document.pdf', 'rb') as f:
file_content = f.read()
# Create new version
version_info = create_document_version(
user=user,
document_uid=document_uid,
file_content=file_content,
file_name='updated_document.pdf',
comment='Updated section 3 with new compliance requirements'
)
if version_info:
print(f"Version {version_info['version_number']} created successfully")
print(f"Version UID: {version_info['UID']}")
print(f"File size: {version_info['file_size']} bytes")
else:
print("Failed to create version")
Best Practices
- Always wrap calls in try-except blocks as the function raises BusinessRuleError on failures
- Ensure the user has CREATE_VERSION permission before calling (enforced by decorator)
- The function is transactional - failures will rollback database changes
- File content should be validated before passing to this function
- The document_uid must reference an existing document or ResourceNotFoundError is raised
- Version numbers are auto-incremented (major.minor format) - do not manually specify
- The function logs extensively - ensure logging is configured appropriately
- Audit trail creation failures are logged but do not fail the entire operation
- Text extraction is currently disabled (commented out) but can be enabled if document_processor is configured
- The function sets the new version as the current version automatically
- File size is calculated from file_content length - ensure content is loaded properly
- Returns None on node/relationship creation failure - always check return value
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function create_document_version_v2 98.8% similar
-
function create_document_version_v3 94.5% similar
-
function upload_document_to_filecloud_v1 79.1% similar
-
function upload_document_to_filecloud 78.0% similar
-
function create_document_version 75.2% similar