deploy-todo / src /services /task_service.py
umar-30's picture
Claude Opus 4.5
Deploy FastAPI backend for Todo application
18ade12
Raw History Blame Contribute Delete
4.04 kB
"""
Task service layer for the Task Management API.
Business logic for task operations with user-scoped data isolation.
Per data-model.md specification.
"""
from datetime import datetime
from typing import List, Optional
from uuid import UUID
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
from ..models.task import Task
from ..schemas.task import TaskCreate, TaskUpdate
class TaskService:
"""Service class for task operations."""
async def create_task(self, db_session: AsyncSession, user_id: str, task_data: TaskCreate) -> Task:
"""Create a new task for the specified user."""
task = Task(
user_id=user_id,
title=task_data.title,
description=task_data.description,
is_completed=False,
created_at=datetime.utcnow(),
updated_at=datetime.utcnow()
)
db_session.add(task)
await db_session.commit()
await db_session.refresh(task)
return task
async def get_tasks_by_user(
self,
db_session: AsyncSession,
user_id: str,
limit: int = 50,
offset: int = 0
) -> tuple[List[Task], int]:
"""Get all tasks for the specified user with pagination."""
# Query for tasks belonging to the user
query = select(Task).where(Task.user_id == user_id)
# Get total count
count_result = await db_session.exec(query)
all_tasks = count_result.all()
total = len(all_tasks)
# Apply pagination
paginated_query = query.offset(offset).limit(limit)
result = await db_session.exec(paginated_query)
tasks = result.all()
return list(tasks), total
async def get_task_by_id(self, db_session: AsyncSession, user_id: str, task_id: UUID) -> Optional[Task]:
"""Get a specific task by ID for the specified user."""
query = select(Task).where(Task.user_id == user_id, Task.id == task_id)
result = await db_session.exec(query)
return result.first()
async def update_task(
self,
db_session: AsyncSession,
user_id: str,
task_id: UUID,
task_data: TaskUpdate
) -> Optional[Task]:
"""Update a specific task for the specified user."""
task = await self.get_task_by_id(db_session, user_id, task_id)
if not task:
return None
# Update fields that are provided in the update data
if task_data.title is not None:
task.title = task_data.title
if task_data.description is not None:
task.description = task_data.description
if task_data.is_completed is not None:
task.is_completed = task_data.is_completed
# Update the timestamp
task.updated_at = datetime.utcnow()
db_session.add(task)
await db_session.commit()
await db_session.refresh(task)
return task
async def delete_task(self, db_session: AsyncSession, user_id: str, task_id: UUID) -> bool:
"""Delete a specific task for the specified user."""
task = await self.get_task_by_id(db_session, user_id, task_id)
if not task:
return False
await db_session.delete(task)
await db_session.commit()
return True
async def toggle_task_completion(
self,
db_session: AsyncSession,
user_id: str,
task_id: UUID
) -> Optional[Task]:
"""Toggle the completion status of a specific task for the specified user."""
task = await self.get_task_by_id(db_session, user_id, task_id)
if not task:
return None
# Toggle the completion status
task.is_completed = not task.is_completed
# Update the timestamp
task.updated_at = datetime.utcnow()
db_session.add(task)
await db_session.commit()
await db_session.refresh(task)
return task
# Create a singleton instance
task_service = TaskService()