Activity Timeline - Show All Logs Fix
Version: 0.234.136
Fixed in: 0.234.136
Issue: Activity timelines for groups and public workspaces were not showing all activity logs, particularly status changes were missing
Problem Description
Root Cause
The activity timeline queries for both groups and public workspaces had hardcoded WHERE c.activity_type IN (...) filters that only included specific activity types. This meant:
- Group status changes weren't appearing in group activity timelines
- Any new or unknown activity types were being filtered out
- Users couldn't see a complete audit trail of all activities
Specific Issues
- Group Activity Query 1 filtered to only:
group_member_added,group_member_deleted,group_status_change - Group Activity Query 2 filtered to only:
document_creation,document_deletion,document_metadata_update - Workspace Activity Query filtered to only:
document_creation,document_deletion,document_metadata_update,public_workspace_status_change - Backend formatting used wrong field names for group status changes (
from_status/to_statusinstead ofold_status/new_status) - No fallback in backend for unknown activity types (frontend already had fallback)
Solution
1. Remove Activity Type Filters
File: route_backend_control_center.py
Group Query 1 (Member/Status Activities)
Before:
WHERE c.activity_type IN ('group_member_added', 'group_member_deleted', 'group_status_change')
AND c.group.group_id = @group_id
After:
WHERE c.group.group_id = @group_id
Group Query 2 (Document Activities)
Before:
WHERE c.activity_type IN ('document_creation', 'document_deletion', 'document_metadata_update')
AND c.workspace_context.group_id = @group_id
After:
WHERE c.workspace_context.group_id = @group_id
Workspace Query
Before:
WHERE c.activity_type IN ('document_creation', 'document_deletion', 'document_metadata_update', 'public_workspace_status_change')
AND c.workspace_context.public_workspace_id = @workspace_id
After:
WHERE c.workspace_context.public_workspace_id = @workspace_id
2. Fix Status Change Field Mapping
File: route_backend_control_center.py
Before:
formatted['status_change'] = {
'from_status': status_change.get('from_status'),
'to_status': status_change.get('to_status')
}
After:
formatted['status_change'] = {
'from_status': status_change.get('old_status'), # Use old_status from log
'to_status': status_change.get('new_status') # Use new_status from log
}
This matches the actual structure saved in functions_activity_logging.py which uses old_status and new_status.
3. Add Backend Fallback for Unknown Activity Types
File: route_backend_control_center.py
Group Activity Formatting
else:
# Fallback for unknown activity types - still show them!
formatted['icon'] = 'circle'
formatted['color'] = 'secondary'
# Keep any additional data that might be in the activity
if activity.get('status_change'):
formatted['status_change'] = activity.get('status_change')
if activity.get('document'):
formatted['document'] = activity.get('document')
if activity.get('group'):
formatted['group'] = activity.get('group')
Workspace Activity Formatting
else:
# Fallback for unknown activity types - still show them!
formatted['icon'] = 'circle'
formatted['color'] = 'secondary'
# Keep any additional data that might be in the activity
if activity.get('status_change'):
formatted['status_change'] = activity.get('status_change')
if activity.get('document'):
formatted['document'] = activity.get('document')
if activity.get('workspace_context'):
formatted['workspace_context'] = activity.get('workspace_context')
4. Add Missing Fields to Queries
File: route_backend_control_center.py
Added c.status_change and c.changed_by to all queries to ensure these fields are available for all activity types.
Files Modified
Backend
application/single_app/route_backend_control_center.py:- Line ~3033: Removed activity type filter from Group Query 1
- Line ~3053: Removed activity type filter from Group Query 2
- Line ~3039: Added
c.changed_byto Group Query 1 - Line ~3061: Added
c.status_change, c.changed_byto Group Query 2 - Line ~3187: Fixed group status change field mapping
- Line ~3197: Added fallback for unknown activity types (groups)
- Line ~3951: Removed activity type filter from Workspace Query
- Line ~3957: Added
c.status_change, c.changed_byto Workspace Query - Line ~4047: Added fallback for unknown activity types (workspaces)
Version
application/single_app/config.py:- Line 91: Updated VERSION to "0.234.136"
Testing
Test Case 1: Group Status Changes Appear
- Change a group's status in Control Center
- View the group's activity timeline
- Expected: Status change activity appears with old → new status badges
- Result: ✅ Status changes now visible
Test Case 2: Workspace Status Changes Appear
- Change a workspace's status in Control Center
- View the workspace's activity timeline
- Expected: Status change activity appears with old → new status badges
- Result: ✅ Status changes now visible
Test Case 3: All Activity Types Shown
- Perform various actions: upload document, add member, change status, delete document
- View activity timeline
- Expected: All activities appear in chronological order
- Result: ✅ Complete audit trail visible
Test Case 4: Unknown Activity Types
- If a new activity type is added to the system
- View activity timeline
- Expected: New activity type appears with generic icon and description
- Result: ✅ Fallback rendering works correctly
Benefits
Complete Audit Trail
- Before: Selective activities shown, status changes missing
- After: ALL activities visible in timeline
Future-Proof
- Before: New activity types silently filtered out
- After: All activity types shown with appropriate fallback formatting
Consistency
- Before: Field name mismatches caused empty displays
- After: Correct field mappings ensure proper data display
User Experience
- Before: Incomplete activity history, users missed important changes
- After: Complete history with rich formatting for known types
Query Performance Note
Removing the activity type filters means queries will return more results, but:
- Queries are still scoped to specific group_id or workspace_id
- Time range filters (default 30 days) still apply
- Results are sorted by timestamp DESC
- The additional data provides valuable audit trail information
The performance impact is minimal and the benefits of complete audit visibility outweigh any minor query time increase.
Activity Types Now Shown
Groups
- ✅
group_member_added- Member additions with role - ✅
group_member_deleted- Member removals - ✅
group_status_change- Status changes with old → new badges - ✅
document_creation- Document uploads - ✅
document_deletion- Document deletions - ✅
document_metadata_update- Document updates - ✅
conversation_creation- Chat conversations - ✅ Any future activity types (with fallback rendering)
Public Workspaces
- ✅
public_workspace_status_change- Status changes - ✅
document_creation- Document uploads - ✅
document_deletion- Document deletions - ✅
document_metadata_update- Document updates - ✅ Any future activity types (with fallback rendering)
Related Activity Log Structure
Activity logs are stored in the activity_logs Cosmos DB container with this structure:
{
"id": "uuid",
"activity_type": "group_status_change",
"timestamp": "2024-01-15T10:30:00.000Z",
"group": {
"group_id": "group-123",
"group_name": "Engineering Team"
},
"status_change": {
"old_status": "active",
"new_status": "locked",
"changed_at": "2024-01-15T10:30:00.000Z",
"reason": "Security review"
},
"changed_by": {
"user_id": "user-456",
"email": "admin@example.com"
},
"workspace_context": {
"group_id": "group-123"
}
}
Frontend Rendering
Both GroupManager.renderActivityItem() in control_center.html and WorkspaceManager.renderActivityItem() in workspace-manager.js already had default case fallback rendering, so no frontend changes were needed.
default:
title = activity.type || 'Activity';
content = `<div class="text-muted small">${escapeHtml(activity.description || 'No details available')}</div>`;
This ensures any activity type, whether known or unknown, is displayed to the user.