diff --git a/backend/routers/activities.py b/backend/routers/activities.py index 03bfc51..b8f9bbf 100644 --- a/backend/routers/activities.py +++ b/backend/routers/activities.py @@ -5,7 +5,7 @@ from typing import List, Optional from datetime import datetime, timedelta from database import get_db -from models.user import User +from models.user import User, UserRole from models.activity import Activity, ActivityType from models.project import ProjectMember from schemas.activity import ActivityResponse @@ -26,15 +26,17 @@ def get_project_activities( current_user: User = Depends(get_current_user) ): """Get activity feed for a specific project (excludes activities for deleted records).""" - # Verify user has access to the project - member = db.query(ProjectMember).filter( - ProjectMember.project_id == project_id, - ProjectMember.user_id == current_user.id - ).first() - - if not member and not current_user.is_admin: - from fastapi import HTTPException - raise HTTPException(status_code=403, detail="Access denied to this project") + # Only artists are restricted to their explicit project memberships; coordinators, + # directors, developers, and admins have access to all projects (matches shots.py/assets.py). + if current_user.role == UserRole.ARTIST: + member = db.query(ProjectMember).filter( + ProjectMember.project_id == project_id, + ProjectMember.user_id == current_user.id + ).first() + + if not member: + from fastapi import HTTPException + raise HTTPException(status_code=403, detail="Access denied to this project") # Use ActivityService to get activities excluding deleted records activities = ActivityService.get_activities_excluding_deleted( @@ -66,15 +68,17 @@ def get_task_activities( from fastapi import HTTPException raise HTTPException(status_code=404, detail="Task not found") - # Check if user is a member of the project - member = db.query(ProjectMember).filter( - ProjectMember.project_id == task.project_id, - ProjectMember.user_id == current_user.id - ).first() - - if not member and not current_user.is_admin: - from fastapi import HTTPException - raise HTTPException(status_code=403, detail="Access denied to this task") + # Only artists are restricted to their explicit project memberships; coordinators, + # directors, developers, and admins have access to all tasks (matches shots.py/assets.py). + if current_user.role == UserRole.ARTIST: + member = db.query(ProjectMember).filter( + ProjectMember.project_id == task.project_id, + ProjectMember.user_id == current_user.id + ).first() + + if not member: + from fastapi import HTTPException + raise HTTPException(status_code=403, detail="Access denied to this task") # Use ActivityService to get activities excluding deleted records activities = ActivityService.get_activities_excluding_deleted( @@ -122,34 +126,10 @@ def get_recent_activities( current_user: User = Depends(get_current_user) ): """Get recent activities from all projects the user has access to (excludes activities for deleted records).""" - # Get all projects the user is a member of - project_ids = db.query(ProjectMember.project_id).filter( - ProjectMember.user_id == current_user.id - ).all() - - project_ids = [pid[0] for pid in project_ids] - - if not project_ids and not current_user.is_admin: - return [] - - # For non-admin users, filter by their project access - if not current_user.is_admin: - # Get activities from user's projects, excluding deleted records - all_activities = [] - for project_id in project_ids: - activities = ActivityService.get_activities_excluding_deleted( - db=db, - project_id=project_id, - skip=0, - limit=limit * 2 # Get more to account for filtering - ) - all_activities.extend(activities) - - # Sort by created_at and apply pagination - all_activities.sort(key=lambda x: x.created_at, reverse=True) - return all_activities[skip:skip + limit] - else: - # Admin gets all activities excluding deleted records + # Only artists are restricted to their explicit project memberships; coordinators, + # directors, developers, and admins see recent activity across all projects + # (matches shots.py/assets.py). + if current_user.role != UserRole.ARTIST: activities = ActivityService.get_activities_excluding_deleted( db=db, skip=skip, @@ -157,6 +137,30 @@ def get_recent_activities( ) return activities + # Get all projects the artist is a member of + project_ids = db.query(ProjectMember.project_id).filter( + ProjectMember.user_id == current_user.id + ).all() + + project_ids = [pid[0] for pid in project_ids] + + if not project_ids: + return [] + + all_activities = [] + for project_id in project_ids: + activities = ActivityService.get_activities_excluding_deleted( + db=db, + project_id=project_id, + skip=0, + limit=limit * 2 # Get more to account for filtering + ) + all_activities.extend(activities) + + # Sort by created_at and apply pagination + all_activities.sort(key=lambda x: x.created_at, reverse=True) + return all_activities[skip:skip + limit] + # Admin-only endpoints that include activities for deleted records @router.get("/admin/project/{project_id}/all", response_model=List[ActivityResponse])