tracker/src/tracker/api/steps.py
markov 0c44a8b384
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s
Fix #4 hotfix: restore missing router = APIRouter in steps.py
2026-02-26 15:17:35 +01:00

88 lines
2.5 KiB
Python

"""Steps API — CRUD for task steps (checklist)."""
import uuid
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from ..database import get_db
from ..models import Step, Task
from .schemas import StepOut
from .converters import step_out
router = APIRouter(tags=["steps"])
class StepCreate(BaseModel):
title: str
class StepUpdate(BaseModel):
title: str | None = None
done: bool | None = None
@router.get("/tasks/{task_id}/steps", response_model=list[StepOut])
async def list_steps(task_id: str, db: AsyncSession = Depends(get_db)):
result = await db.execute(
select(Step).where(Step.task_id == uuid.UUID(task_id)).order_by(Step.position)
)
return [step_out(s) for s in result.scalars()]
@router.post("/tasks/{task_id}/steps", response_model=StepOut)
async def create_step(task_id: str, req: StepCreate, db: AsyncSession = Depends(get_db)):
task = await db.get(Task, uuid.UUID(task_id))
if not task:
raise HTTPException(404, "Task not found")
result = await db.execute(
select(func.coalesce(func.max(Step.position), -1)).where(Step.task_id == task.id)
)
max_pos = result.scalar()
step = Step(
task_id=task.id,
title=req.title,
done=False,
position=max_pos + 1,
)
db.add(step)
await db.commit()
await db.refresh(step)
return step_out(step)
@router.patch("/tasks/{task_id}/steps/{step_id}", response_model=StepOut)
async def update_step(task_id: str, step_id: str, req: StepUpdate, db: AsyncSession = Depends(get_db)):
result = await db.execute(
select(Step).where(Step.id == uuid.UUID(step_id), Step.task_id == uuid.UUID(task_id))
)
step = result.scalar_one_or_none()
if not step:
raise HTTPException(404, "Step not found")
if req.title is not None:
step.title = req.title
if req.done is not None:
step.done = req.done
await db.commit()
await db.refresh(step)
return step_out(step)
@router.delete("/tasks/{task_id}/steps/{step_id}")
async def delete_step(task_id: str, step_id: str, db: AsyncSession = Depends(get_db)):
result = await db.execute(
select(Step).where(Step.id == uuid.UUID(step_id), Step.task_id == uuid.UUID(task_id))
)
step = result.scalar_one_or_none()
if not step:
raise HTTPException(404, "Step not found")
await db.delete(step)
await db.commit()
return {"ok": True}