File size: 6,026 Bytes
4a693cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
################################################################################
# FILE: backend/app/api/v1/tasks.py
# VERSION: 4.0.0 | SYSTEM: Orbit Protocol
# IDENTITY: Task Management / Life Admin Router - V4.0.0 Upgrades
################################################################################

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from typing import List, Optional
import logging
from datetime import datetime

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from app.db.session import get_db
from app.models.study import StudyTask, BrainRotLevel

from app.services.governor import governor

logger = logging.getLogger("orbit_tasks")
router = APIRouter()

class TaskCreatePayload(BaseModel):
    title: str
    subject: str = "Life Admin"
    brain_rot_level: str = "mid"
    is_reminder: bool = False
    due_date: Optional[datetime] = None

class TaskCompletePayload(BaseModel):
    remarks: Optional[str] = None

@router.get("/", status_code=status.HTTP_200_OK)
async def get_all_tasks(db: AsyncSession = Depends(get_db)):
    """Fetch all active tasks with full metadata."""
    try:
        current_vibe = governor.get_current_recommendation() if hasattr(governor, 'get_current_recommendation') else "Grind Mode Activated"

        result = await db.execute(select(StudyTask))
        tasks = result.scalars().all()

        task_list = [
            {
                "id": t.id,
                "title": t.title,
                "subject": t.subject,
                "brain_rot_level": t.brain_rot_level.value if hasattr(t.brain_rot_level, 'value') else t.brain_rot_level,
                "due_date": t.due_date.isoformat() if t.due_date else None,
                "is_reminder": t.is_reminder,
                "completed": t.completed,
                "remarks": t.remarks
            } for t in tasks
        ]

        return {
            "status": "bullish 📈",
            "message": "Tasks loaded successfully.",
            "governor_status": current_vibe,
            "data": task_list
        }
    except Exception as e:
        logger.error(f"Task fetch liquidated: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to fetch tasks.")

@router.get("/pending", status_code=status.HTTP_200_OK)
async def get_pending_tasks(db: AsyncSession = Depends(get_db)):
    """Fetch only the pending tasks for the Android sorting logic."""
    try:
        logger.info("Mobile hit /pending. Sorting by Brain Rot level soon.")

        result = await db.execute(select(StudyTask).where(StudyTask.completed == False))
        tasks = result.scalars().all()

        task_list = [
            {
                "id": t.id,
                "title": t.title,
                "subject": t.subject,
                "brain_rot_level": t.brain_rot_level.value if hasattr(t.brain_rot_level, 'value') else t.brain_rot_level,
                "due_date": t.due_date.isoformat() if t.due_date else None,
                "is_reminder": t.is_reminder
            } for t in tasks
        ]

        return {
            "status": "bullish 📈",
            "message": "Pending tasks secured.",
            "data": task_list
        }
    except Exception as e:
        logger.error(f"Pending tasks fetch liquidated: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to fetch pending tasks.")

@router.post("/", status_code=status.HTTP_201_CREATED)
async def create_task(task_data: TaskCreatePayload, db: AsyncSession = Depends(get_db)):
    """Inject a new task into the Brain. 🧠"""
    try:
        rot_map = {"chill": BrainRotLevel.CHILL, "mid": BrainRotLevel.MID, "cooked": BrainRotLevel.COOKED}
        safe_rot = rot_map.get(task_data.brain_rot_level.lower(), BrainRotLevel.MID)

        new_task = StudyTask(
            title=task_data.title,
            subject=task_data.subject,
            brain_rot_level=safe_rot,
            is_reminder=task_data.is_reminder,
            due_date=task_data.due_date
        )
        db.add(new_task)
        await db.commit()

        return {
            "status": "success",
            "message": "Task injected into Orbit. 🎯"
        }
    except Exception as e:
        logger.error(f"Failed to create task: {str(e)}")
        await db.rollback()
        raise HTTPException(status_code=400, detail="Task creation failed.")

@router.post("/{task_id}/complete", status_code=status.HTTP_200_OK)
async def complete_task(task_id: int, payload: TaskCompletePayload, db: AsyncSession = Depends(get_db)):
    """The CompleteTask Endpoint: Captures remarks and marks as finished."""
    try:
        logger.info(f"Completing task {task_id} with remarks: {payload.remarks}")
        result = await db.execute(select(StudyTask).where(StudyTask.id == task_id))
        task = result.scalars().first()

        if not task:
            raise HTTPException(status_code=404, detail="Task not found.")

        task.completed = True
        task.remarks = payload.remarks

        await db.commit()
        return {"status": "success", "message": "Task secured and remarks filed. ✅"}
    except Exception as e:
        await db.rollback()
        logger.error(f"Failed to complete task: {str(e)}")
        raise HTTPException(status_code=500, detail="Error completing task.")

@router.delete("/{task_id}", status_code=status.HTTP_200_OK)
async def delete_task(task_id: int, db: AsyncSession = Depends(get_db)):
    """Wipe a task from existence. Hard delete."""
    try:
        result = await db.execute(select(StudyTask).where(StudyTask.id == task_id))
        task = result.scalars().first()
        if task:
            await db.delete(task)
            await db.commit()
            return {"status": "deleted", "message": "Task wiped."}
        return {"status": "error", "message": "Task not found."}
    except Exception as e:
        await db.rollback()
        raise HTTPException(status_code=500, detail="Error deleting task.")