function complete_user_training_by_uid
Completes a user's training assignment for a controlled document by updating the training relationship status, recording completion date and score, and logging the event to the audit trail.
/tf/active/vicechatdev/CDocs/controllers/training_controller.py
349 - 446
moderate
Purpose
This function handles the completion workflow for mandatory training assignments in a document control system. It parses a composite training UID to identify the user and document, validates that users can only complete their own training, optionally processes quiz answers, updates the Neo4j graph database relationship between user and document, and creates an audit trail entry. It's designed for compliance-driven environments where training completion must be tracked and verified.
Source Code
def complete_user_training_by_uid(
user: DocUser,
training_uid: str,
quiz_answers: Dict[str, Any] = None
) -> Dict[str, Any]:
"""
Complete training assignment by training UID.
Args:
user: User completing training
training_uid: Training UID (format: user_uid-document_uid)
quiz_answers: Quiz answers if quiz is required
Returns:
Dictionary with operation status
"""
try:
# Parse the training_uid to get user and document UIDs
# Format is: user_uid-document_uid where both are UUIDs
# UUIDs are 36 characters long, so we split at position 36
if len(training_uid) > 36 and training_uid[36] == '-':
user_uid = training_uid[:36]
document_uid = training_uid[37:] # Skip the separating hyphen
else:
# If the format is unexpected, log it and return error
logger.error(f"Invalid training UID format: {training_uid}")
return {
"success": False,
"message": "Invalid training assignment ID format"
}
# Verify this is the correct user completing their own training
if user_uid != user.uid:
logger.warning(f"User {user.uid} attempting to complete training assignment for user {user_uid}")
return {
"success": False,
"message": "You can only complete your own training assignments"
}
# Check if quiz is required and validate answers
quiz_passed = True
if quiz_answers:
# TODO: Implement quiz validation logic
# For now, assume quiz is passed if answers are provided
quiz_passed = True
# Update the training relationship directly
completion_date = datetime.now().isoformat()
query = """
MATCH (u:User {UID: $user_uid})-[r:REQUIRES_TRAINING]->(d:ControlledDocument {UID: $document_uid})
SET r.status = 'COMPLETED',
r.completed_date = $completion_date,
r.score = $score,
r.progress = 100
RETURN r
"""
score = 100 if quiz_passed else 0
result = db.run_query(query, {
'user_uid': user_uid,
'document_uid': document_uid,
'completion_date': completion_date,
'score': score
})
if not result:
return {
"success": False,
"message": "Training assignment not found"
}
# Log completion event
audit_trail.log_event(
event_type="TRAINING_COMPLETED",
user=user.uid,
resource_uid=document_uid,
resource_type="ControlledDocument",
details={
"training_uid": training_uid,
"completion_date": completion_date,
"score": score,
"quiz_passed": quiz_passed
}
)
return {
"success": True,
"message": "Training completed successfully",
"completion_date": completion_date,
"score": score
}
except Exception as e:
logger.error(f"Error completing training assignment {training_uid}: {e}")
return {
"success": False,
"message": f"Failed to complete training: {e}"
}
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
DocUser | - | positional_or_keyword |
training_uid |
str | - | positional_or_keyword |
quiz_answers |
Dict[str, Any] | None | positional_or_keyword |
Parameter Details
user: DocUser object representing the authenticated user attempting to complete the training. Must have a 'uid' attribute that matches the user_uid portion of the training_uid for authorization.
training_uid: String identifier in the format 'user_uid-document_uid' where both UIDs are 36-character UUIDs separated by a hyphen. This composite key uniquely identifies a specific training assignment relationship.
quiz_answers: Optional dictionary containing quiz responses if the training requires quiz completion. Currently accepts any structure as quiz validation is not fully implemented (marked with TODO). Defaults to None if no quiz is required.
Return Value
Type: Dict[str, Any]
Returns a dictionary with operation status. On success: {'success': True, 'message': 'Training completed successfully', 'completion_date': ISO format datetime string, 'score': integer (100 if quiz passed, 0 otherwise)}. On failure: {'success': False, 'message': error description string}. Possible failure messages include 'Invalid training assignment ID format', 'You can only complete your own training assignments', 'Training assignment not found', or exception details.
Dependencies
typingdatetimeloggingCDocs.configCDocs.models.documentCDocs.models.user_extensionsCDocs.models.trainingCDocs.utilsCDocs.dbCDocs.controllerstraceback
Required Imports
from typing import Dict, Any
from datetime import datetime
import logging
from CDocs.models.user_extensions import DocUser
from CDocs.utils import audit_trail
from CDocs.db import db_operations as db
from CDocs.controllers import log_controller_action
Usage Example
from CDocs.models.user_extensions import DocUser
from CDocs.controllers import log_controller_action
# Assuming user object is already authenticated and retrieved
user = DocUser(uid='12345678-1234-1234-1234-123456789abc', name='John Doe')
# Training UID format: user_uid-document_uid
training_uid = '12345678-1234-1234-1234-123456789abc-87654321-4321-4321-4321-cba987654321'
# Complete training without quiz
result = complete_user_training_by_uid(user, training_uid)
if result['success']:
print(f"Training completed on {result['completion_date']} with score {result['score']}")
else:
print(f"Error: {result['message']}")
# Complete training with quiz answers
quiz_answers = {'question_1': 'answer_a', 'question_2': 'answer_b'}
result = complete_user_training_by_uid(user, training_uid, quiz_answers)
if result['success']:
print(f"Training and quiz completed with score {result['score']}")
Best Practices
- Always ensure the user object is properly authenticated before calling this function
- The training_uid must be exactly in the format 'user_uid-document_uid' with 36-character UUIDs
- Users can only complete their own training assignments - the function enforces this authorization check
- Quiz validation logic is currently incomplete (marked TODO) - quiz_answers are accepted but not validated
- The function uses the @log_controller_action decorator for automatic logging of controller actions
- All database operations are wrapped in try-except blocks for error handling
- Completion events are automatically logged to the audit trail for compliance tracking
- The function sets progress to 100 and status to 'COMPLETED' upon successful completion
- Score is set to 100 if quiz is passed (or no quiz required), 0 otherwise
- Consider implementing proper quiz validation logic before using in production with quiz requirements
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function complete_user_training 89.5% similar
-
function get_training_assignment 76.3% similar
-
function get_document_training_info 76.2% similar
-
function remove_training_assignment 74.6% similar
-
function enable_document_training 73.8% similar