File size: 4,036 Bytes
18ade12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
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()