diff --git a/backend/app/routers/projects.py b/backend/app/routers/projects.py
index b95b32b..2f85ce0 100644
--- a/backend/app/routers/projects.py
+++ b/backend/app/routers/projects.py
@@ -44,8 +44,8 @@ def _project_load_options():
selectinload(Project.tasks).selectinload(ProjectTask.comments).selectinload(TaskComment.user),
selectinload(Project.tasks).selectinload(ProjectTask.subtasks).selectinload(ProjectTask.comments).selectinload(TaskComment.user),
selectinload(Project.tasks).selectinload(ProjectTask.subtasks).selectinload(ProjectTask.subtasks),
- selectinload(Project.tasks).selectinload(ProjectTask.assignments),
- selectinload(Project.tasks).selectinload(ProjectTask.subtasks).selectinload(ProjectTask.assignments),
+ selectinload(Project.tasks).selectinload(ProjectTask.assignments).selectinload(ProjectTaskAssignment.user),
+ selectinload(Project.tasks).selectinload(ProjectTask.subtasks).selectinload(ProjectTask.assignments).selectinload(ProjectTaskAssignment.user),
selectinload(Project.members),
]
@@ -56,8 +56,8 @@ def _task_load_options():
selectinload(ProjectTask.comments).selectinload(TaskComment.user),
selectinload(ProjectTask.subtasks).selectinload(ProjectTask.comments),
selectinload(ProjectTask.subtasks).selectinload(ProjectTask.subtasks),
- selectinload(ProjectTask.assignments),
- selectinload(ProjectTask.subtasks).selectinload(ProjectTask.assignments),
+ selectinload(ProjectTask.assignments).selectinload(ProjectTaskAssignment.user),
+ selectinload(ProjectTask.subtasks).selectinload(ProjectTask.assignments).selectinload(ProjectTaskAssignment.user),
]
diff --git a/backend/app/schemas/project_task_assignment.py b/backend/app/schemas/project_task_assignment.py
index 4d21f1f..27bbaff 100644
--- a/backend/app/schemas/project_task_assignment.py
+++ b/backend/app/schemas/project_task_assignment.py
@@ -1,4 +1,4 @@
-from pydantic import BaseModel, ConfigDict, Field
+from pydantic import BaseModel, ConfigDict, Field, model_validator
from datetime import datetime
@@ -17,3 +17,19 @@ class TaskAssignmentResponse(BaseModel):
created_at: datetime
model_config = ConfigDict(from_attributes=True)
+
+ @model_validator(mode="before")
+ @classmethod
+ def resolve_user_name(cls, data): # type: ignore[override]
+ """Populate user_name from eagerly loaded user relationship."""
+ if hasattr(data, "user") and data.user is not None:
+ if not getattr(data, "user_name", None):
+ data = dict(
+ id=data.id,
+ task_id=data.task_id,
+ user_id=data.user_id,
+ assigned_by=data.assigned_by,
+ user_name=data.user.username,
+ created_at=data.created_at,
+ )
+ return data
diff --git a/frontend/src/components/projects/TaskRow.tsx b/frontend/src/components/projects/TaskRow.tsx
index 8a94f01..ebea04c 100644
--- a/frontend/src/components/projects/TaskRow.tsx
+++ b/frontend/src/components/projects/TaskRow.tsx
@@ -135,12 +135,21 @@ export default function TaskRow({
{hasSubtasks ? `${completedSubtasks}/${task.subtasks.length}` : '—'}
- {/* Assignee avatars */}
- {task.assignments && task.assignments.length > 0 && (
-
-