diff --git a/src/tracker/api/tasks.py b/src/tracker/api/tasks.py index 859e6c4..7ff74f7 100644 --- a/src/tracker/api/tasks.py +++ b/src/tracker/api/tasks.py @@ -11,6 +11,7 @@ from sqlalchemy.orm import selectinload, joinedload from tracker.database import get_db from tracker.models import Task, Step, Project, Member, Message, Chat +from tracker.api.auth import get_current_member router = APIRouter(tags=["tasks"]) @@ -231,6 +232,7 @@ async def get_task(task_id: str, db: AsyncSession = Depends(get_db)): async def create_task( project_slug: str = Query(...), req: TaskCreate = ..., + current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db), ): # Find project @@ -298,14 +300,14 @@ async def create_task( async def update_task( task_id: str, req: TaskUpdate, - actor: Optional[str] = Query(None, description="Who made the change"), + current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db), ): task = await _get_task(task_id, db) slug = task.project.slug if task.project else "" prefix = slug[:2].upper() if slug else "XX" key = f"{prefix}-{task.number}" - who = f"@{actor}" if actor else "Кто-то" + who = f"@{current_member.slug}" old_status = task.status old_assignee = task.assignee_slug @@ -338,7 +340,7 @@ async def update_task( chat_text=f"{key}: {old_status} → {req.status}", task_text=f"{who} изменил статус: {old_status} → {req.status} ({now_str})", project_slug=slug, - actor_slug=actor or "system", + actor_slug=current_member.slug, ) if req.assignee_slug is not None and req.assignee_slug != old_assignee: if req.assignee_slug: @@ -347,7 +349,7 @@ async def update_task( chat_text=f"{key}: назначена на @{req.assignee_slug}", task_text=f"{who} назначил задачу на @{req.assignee_slug} ({now_str})", project_slug=slug, - actor_slug=actor or "system", + actor_slug=current_member.slug, ) else: await _system_message( @@ -355,7 +357,7 @@ async def update_task( chat_text=f"{key}: исполнитель снят", task_text=f"{who} снял исполнителя @{old_assignee} ({now_str})", project_slug=slug, - actor_slug=actor or "system", + actor_slug=current_member.slug, ) await db.commit() @@ -375,7 +377,7 @@ async def update_task( @router.delete("/tasks/{task_id}") -async def delete_task(task_id: str, db: AsyncSession = Depends(get_db)): +async def delete_task(task_id: str, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): task = await _get_task(task_id, db) project_id = str(task.project_id) task_data = {"id": str(task.id), "project_id": project_id} @@ -387,8 +389,9 @@ async def delete_task(task_id: str, db: AsyncSession = Depends(get_db)): @router.post("/tasks/{task_id}/take", response_model=TaskOut) -async def take_task(task_id: str, slug: str = Query(...), db: AsyncSession = Depends(get_db)): +async def take_task(task_id: str, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): """Atomically take a task — only if unassigned and in backlog/todo.""" + slug = current_member.slug task = await _get_task(task_id, db) if task.assignee_slug: raise HTTPException(409, f"Task already assigned to {task.assignee_slug}") @@ -431,7 +434,7 @@ async def take_task(task_id: str, slug: str = Query(...), db: AsyncSession = Dep @router.post("/tasks/{task_id}/reject") -async def reject_task(task_id: str, req: RejectRequest, db: AsyncSession = Depends(get_db)): +async def reject_task(task_id: str, req: RejectRequest, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): """Reject a task with reason — unassign and return to todo.""" task = await _get_task(task_id, db) old_assignee = task.assignee_slug @@ -456,7 +459,7 @@ async def reject_task(task_id: str, req: RejectRequest, db: AsyncSession = Depen @router.post("/tasks/{task_id}/assign", response_model=TaskOut) -async def assign_task(task_id: str, req: AssignRequest, db: AsyncSession = Depends(get_db)): +async def assign_task(task_id: str, req: AssignRequest, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): """Assign task to a member.""" # Verify assignee exists result = await db.execute(select(Member).where(Member.slug == req.assignee_slug)) @@ -495,7 +498,8 @@ async def assign_task(task_id: str, req: AssignRequest, db: AsyncSession = Depen @router.post("/tasks/{task_id}/watch") -async def watch_task(task_id: str, slug: str = Query(...), db: AsyncSession = Depends(get_db)): +async def watch_task(task_id: str, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): + slug = current_member.slug task = await _get_task(task_id, db) if slug not in (task.watchers or []): task.watchers = (task.watchers or []) + [slug] @@ -504,7 +508,8 @@ async def watch_task(task_id: str, slug: str = Query(...), db: AsyncSession = De @router.delete("/tasks/{task_id}/watch") -async def unwatch_task(task_id: str, slug: str = Query(...), db: AsyncSession = Depends(get_db)): +async def unwatch_task(task_id: str, current_member: Member = Depends(get_current_member), db: AsyncSession = Depends(get_db)): + slug = current_member.slug task = await _get_task(task_id, db) task.watchers = [w for w in (task.watchers or []) if w != slug] await db.commit()