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:
ajaysi
2026-03-08 22:51:17 +05:30

View File

@@ -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: