Spaces:
Sleeping
Sleeping
dhruv575 commited on
Commit ·
ea2d2fc
1
Parent(s): 358b1a6
Better logging in backend
Browse files- controllers/department_controller.py +100 -1
- controllers/user_controller.py +7 -1
- models/department.py +16 -1
- models/user.py +36 -2
- routes/department_routes.py +6 -2
controllers/department_controller.py
CHANGED
|
@@ -281,11 +281,32 @@ def add_member(department_id):
|
|
| 281 |
|
| 282 |
def get_department_members(department_id, current_user=None):
|
| 283 |
"""Get all members of a department"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
department = Department.find_by_id(department_id)
|
| 285 |
if not department:
|
|
|
|
| 286 |
return jsonify({'message': 'Department not found'}), 404
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
users = User.find_by_department(department_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
return jsonify({'members': [user.to_dict() for user in users]}), 200
|
| 290 |
|
| 291 |
def remove_member(department_id, user_id):
|
|
@@ -338,4 +359,82 @@ def update_member_permissions(department_id, user_id):
|
|
| 338 |
if user.save():
|
| 339 |
return jsonify({'message': 'User permissions updated successfully', 'user': user.to_dict()}), 200
|
| 340 |
else:
|
| 341 |
-
return jsonify({'message': 'Failed to update user permissions'}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
|
| 282 |
def get_department_members(department_id, current_user=None):
|
| 283 |
"""Get all members of a department"""
|
| 284 |
+
# Log input parameters
|
| 285 |
+
logger.info(f"get_department_members called with department_id: {department_id}")
|
| 286 |
+
if current_user:
|
| 287 |
+
logger.info(f"Current user: {current_user._id}, {current_user.email}, Department: {current_user.department_id}")
|
| 288 |
+
|
| 289 |
+
# Find department by ID
|
| 290 |
department = Department.find_by_id(department_id)
|
| 291 |
if not department:
|
| 292 |
+
logger.error(f"Department with ID {department_id} not found")
|
| 293 |
return jsonify({'message': 'Department not found'}), 404
|
| 294 |
|
| 295 |
+
# Log department info
|
| 296 |
+
logger.info(f"Found department: {department.name}, ID: {department._id}")
|
| 297 |
+
logger.info(f"Department members list (raw): {department.members}")
|
| 298 |
+
logger.info(f"Department has {len(department.members)} members in its members array")
|
| 299 |
+
|
| 300 |
+
# Find users by department
|
| 301 |
+
logger.info(f"Calling User.find_by_department with department_id: {department_id}")
|
| 302 |
users = User.find_by_department(department_id)
|
| 303 |
+
|
| 304 |
+
# Log result
|
| 305 |
+
logger.info(f"User.find_by_department returned {len(users)} users")
|
| 306 |
+
for user in users:
|
| 307 |
+
logger.info(f"Found user: {user._id}, {user.email}, Department: {user.department_id}")
|
| 308 |
+
|
| 309 |
+
# Return response
|
| 310 |
return jsonify({'members': [user.to_dict() for user in users]}), 200
|
| 311 |
|
| 312 |
def remove_member(department_id, user_id):
|
|
|
|
| 359 |
if user.save():
|
| 360 |
return jsonify({'message': 'User permissions updated successfully', 'user': user.to_dict()}), 200
|
| 361 |
else:
|
| 362 |
+
return jsonify({'message': 'Failed to update user permissions'}), 500
|
| 363 |
+
|
| 364 |
+
def debug_department(department_id):
|
| 365 |
+
"""Debug endpoint to get detailed information about a department and its members"""
|
| 366 |
+
logger.info(f"debug_department called with department_id: {department_id}")
|
| 367 |
+
|
| 368 |
+
# Find department directly from MongoDB
|
| 369 |
+
from db import get_departments_collection, get_users_collection
|
| 370 |
+
from bson import ObjectId
|
| 371 |
+
|
| 372 |
+
dept_id_obj = ObjectId(department_id) if isinstance(department_id, str) else department_id
|
| 373 |
+
logger.info(f"Looking up department with ObjectId: {dept_id_obj}")
|
| 374 |
+
|
| 375 |
+
# Get raw department data
|
| 376 |
+
departments_collection = get_departments_collection()
|
| 377 |
+
department_data = departments_collection.find_one({"_id": dept_id_obj})
|
| 378 |
+
|
| 379 |
+
if not department_data:
|
| 380 |
+
logger.error(f"Department with ID {department_id} not found in database")
|
| 381 |
+
return jsonify({'message': 'Department not found'}), 404
|
| 382 |
+
|
| 383 |
+
# Get department object
|
| 384 |
+
department = Department.find_by_id(department_id)
|
| 385 |
+
|
| 386 |
+
# Get users collection
|
| 387 |
+
users_collection = get_users_collection()
|
| 388 |
+
|
| 389 |
+
# Find all users in database
|
| 390 |
+
all_users = list(users_collection.find())
|
| 391 |
+
logger.info(f"Total users in database: {len(all_users)}")
|
| 392 |
+
|
| 393 |
+
# Collect user info for all department members
|
| 394 |
+
member_info = []
|
| 395 |
+
for member_id in department_data.get('members', []):
|
| 396 |
+
# Try to find user by ID
|
| 397 |
+
user_data = users_collection.find_one({"_id": member_id})
|
| 398 |
+
if user_data:
|
| 399 |
+
member_info.append({
|
| 400 |
+
"user_id": str(member_id),
|
| 401 |
+
"found_in_db": True,
|
| 402 |
+
"email": user_data.get('email'),
|
| 403 |
+
"name": user_data.get('name'),
|
| 404 |
+
"department_id": str(user_data.get('department_id')) if user_data.get('department_id') else None
|
| 405 |
+
})
|
| 406 |
+
else:
|
| 407 |
+
member_info.append({
|
| 408 |
+
"user_id": str(member_id),
|
| 409 |
+
"found_in_db": False
|
| 410 |
+
})
|
| 411 |
+
|
| 412 |
+
# Find all users with this department_id
|
| 413 |
+
users_with_dept = list(users_collection.find({"department_id": dept_id_obj}))
|
| 414 |
+
logger.info(f"Found {len(users_with_dept)} users with department_id matching {dept_id_obj}")
|
| 415 |
+
|
| 416 |
+
users_info = []
|
| 417 |
+
for user_data in users_with_dept:
|
| 418 |
+
users_info.append({
|
| 419 |
+
"user_id": str(user_data.get('_id')),
|
| 420 |
+
"email": user_data.get('email'),
|
| 421 |
+
"name": user_data.get('name'),
|
| 422 |
+
"in_members_array": any(str(user_data.get('_id')) == str(m) for m in department_data.get('members', []))
|
| 423 |
+
})
|
| 424 |
+
|
| 425 |
+
# Build response with detailed info
|
| 426 |
+
response = {
|
| 427 |
+
"department": {
|
| 428 |
+
"_id": str(department_data.get('_id')),
|
| 429 |
+
"name": department_data.get('name'),
|
| 430 |
+
"raw_members": [str(m) for m in department_data.get('members', [])],
|
| 431 |
+
"member_count": len(department_data.get('members', [])),
|
| 432 |
+
"members_detail": member_info
|
| 433 |
+
},
|
| 434 |
+
"users_with_department_id": {
|
| 435 |
+
"count": len(users_with_dept),
|
| 436 |
+
"users": users_info
|
| 437 |
+
}
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
return jsonify(response), 200
|
controllers/user_controller.py
CHANGED
|
@@ -121,9 +121,15 @@ def create_users_bulk():
|
|
| 121 |
'errors': errors
|
| 122 |
}), 201 if created_users else 400
|
| 123 |
|
| 124 |
-
def get_all_users():
|
| 125 |
"""Get all users"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
users = User.get_all()
|
|
|
|
|
|
|
| 127 |
return jsonify({'users': [user.to_dict() for user in users]}), 200
|
| 128 |
|
| 129 |
def get_user(user_id):
|
|
|
|
| 121 |
'errors': errors
|
| 122 |
}), 201 if created_users else 400
|
| 123 |
|
| 124 |
+
def get_all_users(current_user=None):
|
| 125 |
"""Get all users"""
|
| 126 |
+
logger.info(f"get_all_users called")
|
| 127 |
+
if current_user:
|
| 128 |
+
logger.info(f"Called by user: {current_user._id}, {current_user.email}, Permissions: {current_user.permissions}")
|
| 129 |
+
|
| 130 |
users = User.get_all()
|
| 131 |
+
logger.info(f"Found {len(users)} users in the database")
|
| 132 |
+
|
| 133 |
return jsonify({'users': [user.to_dict() for user in users]}), 200
|
| 134 |
|
| 135 |
def get_user(user_id):
|
models/department.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from bson import ObjectId
|
| 2 |
from datetime import datetime
|
| 3 |
from db import get_departments_collection
|
|
|
|
| 4 |
|
| 5 |
class Department:
|
| 6 |
def __init__(self, name, address, website, members=None, workflows=None, _id=None, created_at=None, updated_at=None):
|
|
@@ -108,28 +109,42 @@ class Department:
|
|
| 108 |
|
| 109 |
def add_member(self, user_id):
|
| 110 |
"""Add a member to department"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
# Convert user_id to ObjectId if it's a string
|
| 112 |
user_id_obj = ObjectId(user_id) if isinstance(user_id, str) else user_id
|
|
|
|
| 113 |
|
| 114 |
# Check if this user is already in the members array
|
| 115 |
for member in self.members:
|
| 116 |
if str(member) == str(user_id_obj):
|
| 117 |
# User already exists in members array
|
|
|
|
| 118 |
return True
|
| 119 |
|
| 120 |
# Add the user to members
|
| 121 |
self.members.append(user_id_obj)
|
|
|
|
|
|
|
| 122 |
|
| 123 |
# Save changes to database
|
| 124 |
departments_collection = get_departments_collection()
|
| 125 |
|
| 126 |
# Directly update the members array using $push to avoid issues with _id
|
|
|
|
| 127 |
result = departments_collection.update_one(
|
| 128 |
{"_id": ObjectId(self._id)},
|
| 129 |
{"$push": {"members": user_id_obj}}
|
| 130 |
)
|
| 131 |
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
def remove_member(self, user_id):
|
| 135 |
"""Remove a member from department"""
|
|
|
|
| 1 |
from bson import ObjectId
|
| 2 |
from datetime import datetime
|
| 3 |
from db import get_departments_collection
|
| 4 |
+
import logging
|
| 5 |
|
| 6 |
class Department:
|
| 7 |
def __init__(self, name, address, website, members=None, workflows=None, _id=None, created_at=None, updated_at=None):
|
|
|
|
| 109 |
|
| 110 |
def add_member(self, user_id):
|
| 111 |
"""Add a member to department"""
|
| 112 |
+
logger = logging.getLogger(__name__)
|
| 113 |
+
|
| 114 |
+
logger.info(f"add_member called with user_id: {user_id}, type: {type(user_id)}")
|
| 115 |
+
logger.info(f"Department ID: {self._id}, Department name: {self.name}")
|
| 116 |
+
logger.info(f"Current members before adding: {self.members}")
|
| 117 |
+
|
| 118 |
# Convert user_id to ObjectId if it's a string
|
| 119 |
user_id_obj = ObjectId(user_id) if isinstance(user_id, str) else user_id
|
| 120 |
+
logger.info(f"Converted user_id to ObjectId: {user_id_obj}, type: {type(user_id_obj)}")
|
| 121 |
|
| 122 |
# Check if this user is already in the members array
|
| 123 |
for member in self.members:
|
| 124 |
if str(member) == str(user_id_obj):
|
| 125 |
# User already exists in members array
|
| 126 |
+
logger.info(f"User {user_id_obj} already exists in members array, skipping")
|
| 127 |
return True
|
| 128 |
|
| 129 |
# Add the user to members
|
| 130 |
self.members.append(user_id_obj)
|
| 131 |
+
logger.info(f"Added user {user_id_obj} to members array")
|
| 132 |
+
logger.info(f"Members after adding: {self.members}")
|
| 133 |
|
| 134 |
# Save changes to database
|
| 135 |
departments_collection = get_departments_collection()
|
| 136 |
|
| 137 |
# Directly update the members array using $push to avoid issues with _id
|
| 138 |
+
logger.info(f"Updating database with $push operation for department {self._id}")
|
| 139 |
result = departments_collection.update_one(
|
| 140 |
{"_id": ObjectId(self._id)},
|
| 141 |
{"$push": {"members": user_id_obj}}
|
| 142 |
)
|
| 143 |
|
| 144 |
+
success = result.modified_count > 0
|
| 145 |
+
logger.info(f"Database update result: modified_count={result.modified_count}, success={success}")
|
| 146 |
+
|
| 147 |
+
return success
|
| 148 |
|
| 149 |
def remove_member(self, user_id):
|
| 150 |
"""Remove a member from department"""
|
models/user.py
CHANGED
|
@@ -2,6 +2,7 @@ import bcrypt
|
|
| 2 |
from bson import ObjectId
|
| 3 |
from datetime import datetime
|
| 4 |
from db import get_users_collection
|
|
|
|
| 5 |
|
| 6 |
class User:
|
| 7 |
def __init__(self, email, name, password=None, permissions="User", position="Officer",
|
|
@@ -114,9 +115,42 @@ class User:
|
|
| 114 |
@classmethod
|
| 115 |
def find_by_department(cls, department_id):
|
| 116 |
"""Find all users in a department"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
users_collection = get_users_collection()
|
| 118 |
-
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
@classmethod
|
| 122 |
def get_all(cls):
|
|
|
|
| 2 |
from bson import ObjectId
|
| 3 |
from datetime import datetime
|
| 4 |
from db import get_users_collection
|
| 5 |
+
import logging
|
| 6 |
|
| 7 |
class User:
|
| 8 |
def __init__(self, email, name, password=None, permissions="User", position="Officer",
|
|
|
|
| 115 |
@classmethod
|
| 116 |
def find_by_department(cls, department_id):
|
| 117 |
"""Find all users in a department"""
|
| 118 |
+
logger = logging.getLogger(__name__)
|
| 119 |
+
|
| 120 |
+
# Log the input department_id
|
| 121 |
+
logger.info(f"find_by_department called with department_id: {department_id}, type: {type(department_id)}")
|
| 122 |
+
|
| 123 |
+
# Ensure department_id is an ObjectId
|
| 124 |
+
department_id_obj = ObjectId(department_id) if isinstance(department_id, str) else department_id
|
| 125 |
+
logger.info(f"Converted department_id to ObjectId: {department_id_obj}, type: {type(department_id_obj)}")
|
| 126 |
+
|
| 127 |
+
# Get all users and log their count
|
| 128 |
users_collection = get_users_collection()
|
| 129 |
+
all_users = list(users_collection.find())
|
| 130 |
+
logger.info(f"Total users in database: {len(all_users)}")
|
| 131 |
+
|
| 132 |
+
# Log some details about each user's department_id for debugging
|
| 133 |
+
for user in all_users:
|
| 134 |
+
user_dept_id = user.get('department_id')
|
| 135 |
+
logger.info(f"User {user.get('_id')} has department_id: {user_dept_id}, type: {type(user_dept_id)}")
|
| 136 |
+
|
| 137 |
+
# Check if the department_id matches as string
|
| 138 |
+
if user_dept_id:
|
| 139 |
+
str_match = str(user_dept_id) == str(department_id_obj)
|
| 140 |
+
obj_match = user_dept_id == department_id_obj
|
| 141 |
+
logger.info(f" String comparison match: {str_match}, Object comparison match: {obj_match}")
|
| 142 |
+
|
| 143 |
+
# Execute the find query
|
| 144 |
+
query = {"department_id": department_id_obj}
|
| 145 |
+
logger.info(f"Executing MongoDB query: {query}")
|
| 146 |
+
users_data = users_collection.find(query)
|
| 147 |
+
|
| 148 |
+
# Convert to list to get count and log result
|
| 149 |
+
users_list = list(users_data)
|
| 150 |
+
logger.info(f"Found {len(users_list)} users with department_id {department_id_obj}")
|
| 151 |
+
|
| 152 |
+
# Convert to User objects and return
|
| 153 |
+
return [cls.from_dict(user_data) for user_data in users_list]
|
| 154 |
|
| 155 |
@classmethod
|
| 156 |
def get_all(cls):
|
routes/department_routes.py
CHANGED
|
@@ -2,7 +2,8 @@ from flask import Blueprint
|
|
| 2 |
from controllers.department_controller import (
|
| 3 |
create_department, get_department, update_department,
|
| 4 |
delete_department, get_all_departments, add_members_csv,
|
| 5 |
-
add_member, get_department_members, remove_member, update_member_permissions
|
|
|
|
| 6 |
)
|
| 7 |
from utils.auth import token_required, admin_required
|
| 8 |
|
|
@@ -27,4 +28,7 @@ department_bp.route('/<department_id>/members', methods=['GET'])(token_required(
|
|
| 27 |
department_bp.route('/<department_id>/members', methods=['POST'])(admin_required(add_member))
|
| 28 |
department_bp.route('/<department_id>/members/csv', methods=['POST'])(admin_required(add_members_csv))
|
| 29 |
department_bp.route('/<department_id>/members/<user_id>', methods=['DELETE'])(admin_required(remove_member))
|
| 30 |
-
department_bp.route('/<department_id>/members/<user_id>/permissions', methods=['PUT'])(admin_required(update_member_permissions))
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from controllers.department_controller import (
|
| 3 |
create_department, get_department, update_department,
|
| 4 |
delete_department, get_all_departments, add_members_csv,
|
| 5 |
+
add_member, get_department_members, remove_member, update_member_permissions,
|
| 6 |
+
debug_department
|
| 7 |
)
|
| 8 |
from utils.auth import token_required, admin_required
|
| 9 |
|
|
|
|
| 28 |
department_bp.route('/<department_id>/members', methods=['POST'])(admin_required(add_member))
|
| 29 |
department_bp.route('/<department_id>/members/csv', methods=['POST'])(admin_required(add_members_csv))
|
| 30 |
department_bp.route('/<department_id>/members/<user_id>', methods=['DELETE'])(admin_required(remove_member))
|
| 31 |
+
department_bp.route('/<department_id>/members/<user_id>/permissions', methods=['PUT'])(admin_required(update_member_permissions))
|
| 32 |
+
|
| 33 |
+
# Debug route
|
| 34 |
+
department_bp.route('/<department_id>/debug', methods=['GET'])(token_required(debug_department))
|