test_task_crm/app/api/v1/tasks/views.py

63 lines
2.2 KiB
Python

"""Task API endpoints backed by TaskService."""
from __future__ import annotations
from datetime import date
from fastapi import APIRouter, Depends, HTTPException, Query, status
from app.api.deps import get_organization_context, get_task_service
from app.models.task import TaskRead
from app.services.organization_service import OrganizationContext
from app.services.task_service import (
TaskDueDateError,
TaskForbiddenError,
TaskListFilters,
TaskOrganizationError,
TaskService,
)
from .models import TaskCreatePayload, to_range_boundary
router = APIRouter(prefix="/tasks", tags=["tasks"])
@router.get("/", response_model=list[TaskRead])
async def list_tasks(
deal_id: int | None = None,
only_open: bool = False,
due_before: date | None = Query(default=None),
due_after: date | None = Query(default=None),
context: OrganizationContext = Depends(get_organization_context),
service: TaskService = Depends(get_task_service),
) -> list[TaskRead]:
"""Filter tasks by deal, state, or due date range."""
filters = TaskListFilters(
deal_id=deal_id,
only_open=only_open,
due_before=to_range_boundary(due_before, end_of_day=True),
due_after=to_range_boundary(due_after, end_of_day=False),
)
tasks = await service.list_tasks(filters=filters, context=context)
return [TaskRead.model_validate(task) for task in tasks]
@router.post("/", response_model=TaskRead, status_code=status.HTTP_201_CREATED)
async def create_task(
payload: TaskCreatePayload,
context: OrganizationContext = Depends(get_organization_context),
service: TaskService = Depends(get_task_service),
) -> TaskRead:
"""Create a task ensuring due-date and ownership constraints."""
try:
task = await service.create_task(payload.to_domain(), context=context)
except TaskDueDateError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
except TaskForbiddenError as exc:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(exc)) from exc
except TaskOrganizationError as exc:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
return TaskRead.model_validate(task)