Spaces:
Sleeping
Sleeping
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.")
|