File size: 3,674 Bytes
dd1b74d
 
 
 
 
 
 
d93340c
dd1b74d
692a6a6
 
 
dd1b74d
 
 
 
 
 
 
 
d93340c
692a6a6
dd1b74d
 
d93340c
8822d62
 
d93340c
8822d62
 
d93340c
dd1b74d
 
d93340c
dd1b74d
 
 
 
 
d93340c
dd1b74d
 
 
 
cfaf51e
d93340c
 
dd1b74d
d93340c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
from datetime import datetime
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session

# These imports now work because of the path fix in the root main.py
from database import get_db, engine, Base
from models.todo import Todo
from models.user import User
from schemas.todo import TodoCreate, TodoUpdate, TodoResponse, TodoListResponse
from services.todo_service import TodoService
from api.routes.auth import router as auth_router
from api.chat_router import router as chat_router
from api.task_router import router as task_router
from middleware.auth import get_current_user

app = FastAPI(
    title="Todo API",
    description="REST API for managing todo items",
    version="2.0.0"
)

# FIX: Use on_event to avoid 'generator object is not an async iterator' error
@app.on_event("startup")
def startup_event():
    print("Backend starting... Creating database tables.")
    Base.metadata.create_all(bind=engine)

# FIX: Allow GitHub Pages to connect
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"], 
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Include All Routers
app.include_router(auth_router, prefix="/api/v1")
app.include_router(chat_router)
app.include_router(task_router, prefix="/api/v1")

@app.get("/")
def health():
    return {"status": "online", "server": "Hugging Face Spaces"}

# --- COMPLETE TODO ROUTES ---

@app.get("/api/v1/todos", response_model=TodoListResponse)
def get_todos(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
    search: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    priority: Optional[str] = Query(None),
    sort_by: Optional[str] = Query("created_at"),
    sort_order: Optional[str] = Query("desc"),
):
    service = TodoService(db, user_id=current_user.id)
    todos = service.get_all(search=search, status=status, priority=priority, sort_by=sort_by, sort_order=sort_order)
    
    # Helper to convert models to response
    def _todo_to_response(todo):
        return TodoResponse(
            id=todo.id, user_id=todo.user_id, title=todo.title,
            description=todo.description, completed=todo.completed,
            priority=todo.priority, tags=todo.tags, due_date=todo.due_date,
            recurrence=todo.recurrence, created_at=todo.created_at, updated_at=todo.updated_at,
            overdue=False if todo.due_date is None or todo.completed else todo.due_date < datetime.utcnow()
        )

    todos_response = [_todo_to_response(t) for t in todos]
    return {"todos": todos_response, "count": len(todos_response), "has_more": False}

@app.post("/api/v1/todos", response_model=TodoResponse, status_code=201)
def create_todo(todo_data: TodoCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    service = TodoService(db, user_id=current_user.id)
    todo = service.create(todo_data)
    # Re-using logic to return response
    return TodoResponse(
        id=todo.id, user_id=todo.user_id, title=todo.title,
        description=todo.description, completed=todo.completed,
        priority=todo.priority, created_at=todo.created_at, updated_at=todo.updated_at
    )

@app.delete("/api/v1/todos/{todo_id}")
def delete_todo(todo_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    service = TodoService(db, user_id=current_user.id)
    if not service.delete(todo_id):
        raise HTTPException(status_code=404, detail="Todo not found")
    return {"message": "Todo deleted successfully"}