Orbit / app /api /v1 /tasks.py
Orbit Automations
Auto-sync from Julius-606/Orbit monorepo
4a693cf
################################################################################
# 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.")