function create_document_v1
Creates a new version of an existing document in a document management system, storing the file in FileCloud and tracking version metadata in Neo4j graph database.
/tf/active/vicechatdev/document_controller_backup.py
497 - 641
complex
Purpose
This function manages document versioning in a controlled document management system. It validates document existence, generates incremental version numbers, stores file content in FileCloud with a structured folder hierarchy, creates version nodes in Neo4j with comprehensive metadata, establishes relationships between documents and versions, updates document revision information, and creates audit trail entries. It's designed for enterprise document control systems requiring version history, compliance tracking, and file storage integration.
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())
# Base folder structure
department_folder = f"/{settings.FILECLOUD_ROOT_FOLDER}/{document['department']}"
doc_type_folder = f"{department_folder}/{document['docType']}"
document_folder = f"{doc_type_folder}/{document['docNumber']}"
filecloudpath = f"{document_folder}/{document['docNumber']}_v{next_revision}.{file_ext}"
# 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,
'fileCloudPath': filecloudpath,
#'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 trails and tracking version creator information.
document_uid: String UUID uniquely identifying the parent document. Must exist in the database or ResourceNotFoundError is raised. Used to link the new version to its parent document.
file_content: Binary bytes content of the file being versioned. Can be any file type. Used to calculate file size and would be uploaded to FileCloud storage (upload logic appears to be external to this function).
file_name: String name of the file including extension (e.g., 'document.pdf'). Used to extract file type/extension and construct the FileCloud storage path.
comment: Optional string comment describing this version or changes made. Defaults to empty string. Stored in version metadata and audit trail for documentation purposes.
Return Value
Type: Dict[str, Any]
Returns a dictionary containing comprehensive version information including: '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', 'fileCloudPath' (full storage path), 'status' ('ACTIVE'), and 'storage_type' ('FILECLOUD'). Returns None if version node or relationship creation fails. Raises BusinessRuleError on general failures.
Dependencies
logginguuiddatetimetypingCDocs.dbCDocs.config.settingsCDocs.models.user_extensionsCDocs.db.schema_managerCDocs.controllerstraceback
Required Imports
from typing import Dict, Any
from datetime import datetime
import uuid
import logging
from CDocs.models.user_extensions import DocUser
from CDocs import db
from CDocs.config import settings
from CDocs.db.schema_manager import NodeLabels, RelTypes
from CDocs.controllers import ResourceNotFoundError, BusinessRuleError
Conditional/Optional Imports
These imports are only needed under specific conditions:
from CDocs.utils import document_processor
Condition: Only needed if text extraction functionality is enabled (currently commented out in the code)
Optionalfrom CDocs.utils.audit_trail import create_audit_entry
Condition: Required for audit trail functionality, but wrapped in try-except so failures don't break version creation
Required (conditional)from CDocs.db.db_operations import get_document
Condition: Required to retrieve and validate the parent document exists
Required (conditional)import traceback
Condition: Used for detailed error logging when exceptions occur
Required (conditional)Usage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers.document_controller import create_document_version
import logging
logger = logging.getLogger(__name__)
# Assume user is authenticated DocUser instance
user = DocUser(uid='user-123', username='john.doe')
# Read file content
with open('updated_policy.pdf', 'rb') as f:
file_content = f.read()
# Create new version
try:
version_info = create_document_version(
user=user,
document_uid='doc-uuid-12345',
file_content=file_content,
file_name='updated_policy.pdf',
comment='Updated compliance requirements for Q4 2024'
)
if version_info:
print(f"Version {version_info['version_number']} created successfully")
print(f"Version UID: {version_info['UID']}")
print(f"FileCloud path: {version_info['fileCloudPath']}")
else:
print("Failed to create version")
except ResourceNotFoundError as e:
print(f"Document not found: {e}")
except BusinessRuleError as e:
print(f"Business rule violation: {e}")
Best Practices
- Ensure the user has CREATE_VERSION permission before calling this function (enforced by decorator but good to verify in calling code)
- Always wrap calls in try-except blocks to handle ResourceNotFoundError and BusinessRuleError exceptions
- Validate file_content is not None and file_name has proper extension before calling
- The function expects document to have 'department', 'docType', 'docNumber', and 'revision' properties - ensure these exist
- File upload to FileCloud appears to be handled externally - ensure upload_document_to_filecloud is called separately with the returned fileCloudPath
- The function uses transaction decorator, so database operations will be rolled back on failure
- Audit trail creation failures are logged but don't fail the version creation - monitor logs for audit issues
- Version numbering increments minor version (1.0 -> 1.1) - major version changes require different logic
- The function returns None on node/relationship creation failure - always check return value before using
- Text extraction is currently commented out but the infrastructure exists - can be enabled by uncommenting document_processor code
- FileCloud folder structure follows pattern: /root/department/docType/docNumber/docNumber_vX.Y.ext
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function download_document_version 73.4% similar
-
function convert_document_to_pdf 71.2% similar
-
function create_document 68.0% similar
-
function get_document_versions 67.7% similar
-
function set_current_version 66.3% similar