Subtasks: load subtasks + parent in task_out
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s

- selectinload(Task.subtasks), joinedload(Task.parent) in _get_task + list_tasks
- SubtaskBrief schema: id, key, title, status, assignee
- TaskOut: subtasks list, parent_key, parent_title
- .unique() for joinedload dedup
This commit is contained in:
markov 2026-02-28 00:03:08 +01:00
parent 502b55b5a9
commit a4ac2a6471
3 changed files with 40 additions and 2 deletions

View File

@ -10,6 +10,7 @@ from .schemas import (
MessageOut,
ProjectFileOut,
StepOut,
SubtaskBrief,
TaskOut,
)
@ -95,6 +96,25 @@ def message_out(m: Message) -> MessageOut:
def task_out(t: Task, project_slug: str = "") -> TaskOut:
prefix = project_slug[:2].upper() if project_slug else "XX"
# Subtasks
subtasks = []
for sub in (t.subtasks or []):
subtasks.append(SubtaskBrief(
id=str(sub.id),
key=f"{prefix}-{sub.number}",
title=sub.title,
status=sub.status,
assignee=member_brief(sub.assignee) if sub.assignee else None,
))
# Parent info
parent_key = None
parent_title = None
if t.parent:
parent_key = f"{prefix}-{t.parent.number}"
parent_title = t.parent.title
return TaskOut(
id=str(t.id),
project_id=str(t.project_id),
@ -116,6 +136,9 @@ def task_out(t: Task, project_slug: str = "") -> TaskOut:
position=t.position,
time_spent=t.time_spent,
steps=[step_out(s) for s in (t.steps or [])],
subtasks=subtasks,
parent_key=parent_key,
parent_title=parent_title,
created_at=t.created_at.isoformat() if t.created_at else "",
updated_at=t.updated_at.isoformat() if t.updated_at else "",
)

View File

@ -47,10 +47,21 @@ class TaskOut(BaseModel):
position: int
time_spent: int
steps: list[StepOut] = []
subtasks: list["SubtaskBrief"] = []
parent_key: str | None = None
parent_title: str | None = None
created_at: str
updated_at: str
class SubtaskBrief(BaseModel):
id: str
key: str
title: str
status: str
assignee: MemberBrief | None = None
class MessageOut(BaseModel):
id: str
chat_id: str | None = None

View File

@ -189,12 +189,14 @@ async def _get_task(task_id: str, db: AsyncSession) -> Task:
select(Task).where(Task.id == uuid.UUID(task_id))
.options(
selectinload(Task.steps),
selectinload(Task.subtasks).joinedload(Task.assignee),
joinedload(Task.project),
joinedload(Task.assignee),
joinedload(Task.reviewer),
joinedload(Task.parent),
)
)
task = result.scalar_one_or_none()
task = result.unique().scalar_one_or_none()
if not task:
raise HTTPException(404, "Task not found")
return task
@ -221,9 +223,11 @@ async def list_tasks(
):
q = select(Task).options(
selectinload(Task.steps),
selectinload(Task.subtasks).joinedload(Task.assignee),
joinedload(Task.project),
joinedload(Task.assignee),
joinedload(Task.reviewer),
joinedload(Task.parent),
)
if project_id:
q = q.where(Task.project_id == uuid.UUID(project_id))
@ -235,7 +239,7 @@ async def list_tasks(
q = q.where(Task.labels.contains([label]))
q = q.order_by(Task.position, Task.created_at)
result = await db.execute(q)
return [task_out(t, t.project.slug if t.project else "") for t in result.scalars()]
return [task_out(t, t.project.slug if t.project else "") for t in result.unique().scalars()]
@router.get("/tasks/{task_id}", response_model=TaskOut)