feat: task key (TE-1) generated on backend, project includes chat_id
Some checks failed
Deploy Tracker / deploy (push) Failing after 0s

This commit is contained in:
Markov 2026-02-22 19:39:59 +01:00
parent 999b049a9d
commit 377817c62e

View File

@ -7,7 +7,7 @@ from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from sqlalchemy.orm import selectinload, joinedload
from tracker.database import get_db
from tracker.models import Task, Step, Project
@ -29,6 +29,7 @@ class TaskOut(BaseModel):
project_id: str
parent_id: str | None = None
number: int
key: str # e.g. "TE-1"
title: str
description: str | None = None
type: str
@ -79,12 +80,14 @@ class AssignRequest(BaseModel):
# --- Helpers ---
def _task_out(t: Task) -> dict:
def _task_out(t: Task, project_slug: str = "") -> dict:
prefix = project_slug[:2].upper() if project_slug else "XX"
return {
"id": str(t.id),
"project_id": str(t.project_id),
"parent_id": str(t.parent_id) if t.parent_id else None,
"number": t.number,
"key": f"{prefix}-{t.number}",
"title": t.title,
"description": t.description,
"type": t.type,
@ -106,7 +109,8 @@ def _task_out(t: Task) -> dict:
async def _get_task(task_id: str, db: AsyncSession) -> Task:
result = await db.execute(
select(Task).where(Task.id == uuid.UUID(task_id)).options(selectinload(Task.steps))
select(Task).where(Task.id == uuid.UUID(task_id))
.options(selectinload(Task.steps), joinedload(Task.project))
)
task = result.scalar_one_or_none()
if not task:
@ -124,7 +128,7 @@ async def list_tasks(
label: Optional[str] = Query(None),
db: AsyncSession = Depends(get_db),
):
q = select(Task).options(selectinload(Task.steps))
q = select(Task).options(selectinload(Task.steps), joinedload(Task.project))
if project_id:
q = q.where(Task.project_id == uuid.UUID(project_id))
if status:
@ -135,13 +139,13 @@ 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) for t in result.scalars()]
return [_task_out(t, t.project.slug if t.project else "") for t in result.scalars()]
@router.get("/tasks/{task_id}", response_model=TaskOut)
async def get_task(task_id: str, db: AsyncSession = Depends(get_db)):
task = await _get_task(task_id, db)
return _task_out(task)
return _task_out(task, task.project.slug if task.project else "")
@router.post("/tasks", response_model=TaskOut)
@ -180,7 +184,7 @@ async def create_task(
await db.refresh(task)
# Load steps
task_full = await _get_task(str(task.id), db)
return _task_out(task_full)
return _task_out(task_full, task_full.project.slug if task_full.project else "")
@router.patch("/tasks/{task_id}", response_model=TaskOut)
@ -208,7 +212,7 @@ async def update_task(task_id: str, req: TaskUpdate, db: AsyncSession = Depends(
await db.commit()
await db.refresh(task)
return _task_out(task)
return _task_out(task, task.project.slug if task.project else "")
@router.delete("/tasks/{task_id}")
@ -232,7 +236,7 @@ async def take_task(task_id: str, slug: str = Query(...), db: AsyncSession = Dep
task.watchers = (task.watchers or []) + [slug]
await db.commit()
await db.refresh(task)
return _task_out(task)
return _task_out(task, task.project.slug if task.project else "")
@router.post("/tasks/{task_id}/reject")
@ -255,7 +259,7 @@ async def assign_task(task_id: str, req: AssignRequest, db: AsyncSession = Depen
task.watchers = (task.watchers or []) + [req.assignee_slug]
await db.commit()
await db.refresh(task)
return _task_out(task)
return _task_out(task, task.project.slug if task.project else "")
@router.post("/tasks/{task_id}/watch")