Merge PR #397: Add typed request model for task status endpoint
- Add TaskStatusEnum to enumerate valid status values (pending, in_progress, completed, skipped, dismissed) - Add TaskStatusUpdateRequest Pydantic model with validation - Constrain completion_notes to max 4000 characters - Automatically enforce schema validation and improve OpenAPI docs - Update set_task_status endpoint to use typed request body - Remove need for manual status validation (FastAPI handles it) - Preserve dependencies normalization helper and all usages - Preserve date validation and narrower exception handling from PR #396 - Keep proper feedback scoring using task.status from database - Keep contextuality validation response fields intact - Maintain all observability and error handling improvements - Improve API robustness through type safety
This commit is contained in:
@@ -2,7 +2,9 @@ from fastapi import APIRouter, Depends, HTTPException
|
|||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
from enum import Enum
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
@@ -31,6 +33,23 @@ def _normalize_dependencies(dependencies: Any) -> list:
|
|||||||
return []
|
return []
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class TaskStatusEnum(str, Enum):
|
||||||
|
pending = "pending"
|
||||||
|
in_progress = "in_progress"
|
||||||
|
completed = "completed"
|
||||||
|
skipped = "skipped"
|
||||||
|
dismissed = "dismissed"
|
||||||
|
|
||||||
|
|
||||||
|
class TaskStatusUpdateRequest(BaseModel):
|
||||||
|
status: TaskStatusEnum = Field(..., description="New task status")
|
||||||
|
completion_notes: Optional[str] = Field(
|
||||||
|
None,
|
||||||
|
max_length=4000,
|
||||||
|
description="Optional notes about task completion or outcome",
|
||||||
|
)
|
||||||
|
|
||||||
async def _index_tasks_to_sif(user_id: str, date: str, tasks: list[dict], label: str):
|
async def _index_tasks_to_sif(user_id: str, date: str, tasks: list[dict], label: str):
|
||||||
svc = TxtaiIntelligenceService(user_id)
|
svc = TxtaiIntelligenceService(user_id)
|
||||||
items = []
|
items = []
|
||||||
@@ -210,15 +229,13 @@ from services.task_memory_service import TaskMemoryService
|
|||||||
@router.post("/tasks/{task_id}/status")
|
@router.post("/tasks/{task_id}/status")
|
||||||
async def set_task_status(
|
async def set_task_status(
|
||||||
task_id: int,
|
task_id: int,
|
||||||
body: Dict[str, Any],
|
body: TaskStatusUpdateRequest,
|
||||||
current_user: dict = Depends(get_current_user),
|
current_user: dict = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
user_id = str(current_user.get("id"))
|
user_id = str(current_user.get("id"))
|
||||||
status = body.get("status")
|
status = body.status.value
|
||||||
if not status:
|
completion_notes = body.completion_notes
|
||||||
raise HTTPException(status_code=400, detail="status is required")
|
|
||||||
completion_notes = body.get("completion_notes")
|
|
||||||
|
|
||||||
task = update_task_status(db, user_id, task_id, status=status, completion_notes=completion_notes)
|
task = update_task_status(db, user_id, task_id, status=status, completion_notes=completion_notes)
|
||||||
if not task:
|
if not task:
|
||||||
|
|||||||
Reference in New Issue
Block a user