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 tracking, permission management, and audit compliance.
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. Size is calculated and stored in metadata. Used for FileCloud upload (though actual upload code is not shown in this snippet).
file_name: String name of the file including extension. Used to extract file type/extension and construct FileCloud storage path. Should include a valid file extension after the last dot.
comment: Optional string comment describing this version. Defaults to empty string. Stored in version metadata and audit trail. Used for version history documentation.
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.1'), file_name, file_size (bytes), file_type (extension), comment, fileCloudPath (full path in FileCloud), status ('ACTIVE'), and storage_type ('FILECLOUD'). Returns None if version node or relationship creation fails. Raises BusinessRuleError on general failures or ResourceNotFoundError if document doesn't exist.
Dependencies
logginguuiddatetimetypingCDocs.dbCDocs.config.settingsCDocs.models.user_extensionsCDocs.db.schema_managerCDocs.controllerstraceback
Required Imports
import logging
import uuid
from datetime import datetime
from typing import Dict, Any
from CDocs import db
from CDocs.config import settings
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
import traceback
Conditional/Optional Imports
These imports are only needed under specific conditions:
from CDocs.utils import document_processor
Condition: Only if text extraction from documents is enabled (currently commented out in the code)
Optionalfrom CDocs.utils import audit_trail
Condition: Required for create_audit_entry function call
Required (conditional)from CDocs.db.db_operations import get_document
Condition: Required for document existence validation
Required (conditional)Usage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers.document_controller import create_document_version
# Assume user is authenticated and has CREATE_VERSION permission
user = DocUser(uid='user-123', username='john.doe')
document_uid = 'doc-uuid-456'
# Read file content
with open('updated_manual.pdf', 'rb') as f:
file_content = f.read()
# Create new version
try:
version_info = create_document_version(
user=user,
document_uid=document_uid,
file_content=file_content,
file_name='updated_manual.pdf',
comment='Updated safety procedures in section 3'
)
print(f"Version created: {version_info['version_number']}")
print(f"Version UID: {version_info['UID']}")
print(f"FileCloud path: {version_info['fileCloudPath']}")
except ResourceNotFoundError as e:
print(f"Document not found: {e}")
except BusinessRuleError as e:
print(f"Failed to create version: {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 provide meaningful comments when creating versions for audit trail purposes
- Handle ResourceNotFoundError and BusinessRuleError exceptions appropriately in calling code
- Ensure file_content is valid binary data before passing to the function
- The function expects documents to have 'department', 'docType', and 'docNumber' properties for FileCloud path construction
- Version numbers are auto-incremented (major.minor format); manual version number specification is not supported
- The function operates within a transaction context (decorator), so database changes are atomic
- Audit trail creation failures are logged but don't fail the entire operation
- The function creates a version node and relationship but doesn't actually upload to FileCloud in the shown code - ensure FileCloud upload is handled separately
- Text extraction is currently disabled (commented out) but can be enabled by uncommenting the document_processor code
- The function sets the new version as the current version automatically by updating document.currentVersionUID
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function download_document_version 74.2% similar
-
function convert_document_to_pdf 71.9% similar
-
function create_document 68.5% similar
-
function get_document_versions 67.7% similar
-
function get_document_edit_url 66.8% similar