forked from Rockachopa/Timmy-time-dashboard
feat: code quality audit + autoresearch integration + infra hardening (#150)
This commit is contained in:
committed by
GitHub
parent
fd0ede0d51
commit
ae3bb1cc21
@@ -1,4 +1,3 @@
|
||||
|
||||
import logging
|
||||
from datetime import date, datetime
|
||||
from typing import List, Optional
|
||||
@@ -8,7 +7,7 @@ from fastapi.responses import HTMLResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dashboard.models.calm import JournalEntry, Task, TaskCertainty, TaskState
|
||||
from dashboard.models.database import SessionLocal, engine, get_db, create_tables
|
||||
from dashboard.models.database import SessionLocal, create_tables, engine, get_db
|
||||
from dashboard.templating import templates
|
||||
|
||||
# Ensure CALM tables exist (safe to call multiple times)
|
||||
@@ -23,11 +22,19 @@ router = APIRouter(tags=["calm"])
|
||||
def get_now_task(db: Session) -> Optional[Task]:
|
||||
return db.query(Task).filter(Task.state == TaskState.NOW).first()
|
||||
|
||||
|
||||
def get_next_task(db: Session) -> Optional[Task]:
|
||||
return db.query(Task).filter(Task.state == TaskState.NEXT).first()
|
||||
|
||||
|
||||
def get_later_tasks(db: Session) -> List[Task]:
|
||||
return db.query(Task).filter(Task.state == TaskState.LATER).order_by(Task.is_mit.desc(), Task.sort_order).all()
|
||||
return (
|
||||
db.query(Task)
|
||||
.filter(Task.state == TaskState.LATER)
|
||||
.order_by(Task.is_mit.desc(), Task.sort_order)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
def promote_tasks(db: Session):
|
||||
# Ensure only one NOW task exists. If multiple, demote extras to NEXT.
|
||||
@@ -38,7 +45,7 @@ def promote_tasks(db: Session):
|
||||
for task_to_demote in now_tasks[1:]:
|
||||
task_to_demote.state = TaskState.NEXT
|
||||
db.add(task_to_demote)
|
||||
db.flush() # Make changes visible
|
||||
db.flush() # Make changes visible
|
||||
|
||||
# If no NOW task, promote NEXT to NOW
|
||||
current_now = db.query(Task).filter(Task.state == TaskState.NOW).first()
|
||||
@@ -47,12 +54,17 @@ def promote_tasks(db: Session):
|
||||
if next_task:
|
||||
next_task.state = TaskState.NOW
|
||||
db.add(next_task)
|
||||
db.flush() # Make changes visible
|
||||
db.flush() # Make changes visible
|
||||
|
||||
# If no NEXT task, promote highest priority LATER to NEXT
|
||||
current_next = db.query(Task).filter(Task.state == TaskState.NEXT).first()
|
||||
if not current_next:
|
||||
later_tasks = db.query(Task).filter(Task.state == TaskState.LATER).order_by(Task.is_mit.desc(), Task.sort_order).all()
|
||||
later_tasks = (
|
||||
db.query(Task)
|
||||
.filter(Task.state == TaskState.LATER)
|
||||
.order_by(Task.is_mit.desc(), Task.sort_order)
|
||||
.all()
|
||||
)
|
||||
if later_tasks:
|
||||
later_tasks[0].state = TaskState.NEXT
|
||||
db.add(later_tasks[0])
|
||||
@@ -60,14 +72,17 @@ def promote_tasks(db: Session):
|
||||
db.commit()
|
||||
|
||||
|
||||
|
||||
# Endpoints
|
||||
@router.get("/calm", response_class=HTMLResponse)
|
||||
async def get_calm_view(request: Request, db: Session = Depends(get_db)):
|
||||
now_task = get_now_task(db)
|
||||
next_task = get_next_task(db)
|
||||
later_tasks_count = len(get_later_tasks(db))
|
||||
return templates.TemplateResponse(request, "calm/calm_view.html", {"now_task": now_task,
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"calm/calm_view.html",
|
||||
{
|
||||
"now_task": now_task,
|
||||
"next_task": next_task,
|
||||
"later_tasks_count": later_tasks_count,
|
||||
},
|
||||
@@ -101,7 +116,7 @@ async def post_morning_ritual(
|
||||
task = Task(
|
||||
title=mit_title,
|
||||
is_mit=True,
|
||||
state=TaskState.LATER, # Initially LATER, will be promoted
|
||||
state=TaskState.LATER, # Initially LATER, will be promoted
|
||||
certainty=TaskCertainty.SOFT,
|
||||
)
|
||||
db.add(task)
|
||||
@@ -113,7 +128,7 @@ async def post_morning_ritual(
|
||||
db.add(journal_entry)
|
||||
|
||||
# Create other tasks
|
||||
for task_title in other_tasks.split('\n'):
|
||||
for task_title in other_tasks.split("\n"):
|
||||
task_title = task_title.strip()
|
||||
if task_title:
|
||||
task = Task(
|
||||
@@ -128,20 +143,29 @@ async def post_morning_ritual(
|
||||
# Set initial NOW/NEXT states
|
||||
# Set initial NOW/NEXT states after all tasks are created
|
||||
if not get_now_task(db) and not get_next_task(db):
|
||||
later_tasks = db.query(Task).filter(Task.state == TaskState.LATER).order_by(Task.is_mit.desc(), Task.sort_order).all()
|
||||
later_tasks = (
|
||||
db.query(Task)
|
||||
.filter(Task.state == TaskState.LATER)
|
||||
.order_by(Task.is_mit.desc(), Task.sort_order)
|
||||
.all()
|
||||
)
|
||||
if later_tasks:
|
||||
# Set the highest priority LATER task to NOW
|
||||
later_tasks[0].state = TaskState.NOW
|
||||
db.add(later_tasks[0])
|
||||
db.flush() # Flush to make the change visible for the next query
|
||||
db.flush() # Flush to make the change visible for the next query
|
||||
|
||||
# Set the next highest priority LATER task to NEXT
|
||||
if len(later_tasks) > 1:
|
||||
later_tasks[1].state = TaskState.NEXT
|
||||
db.add(later_tasks[1])
|
||||
db.commit() # Commit changes after initial NOW/NEXT setup
|
||||
db.commit() # Commit changes after initial NOW/NEXT setup
|
||||
|
||||
return templates.TemplateResponse(request, "calm/calm_view.html", {"now_task": get_now_task(db),
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"calm/calm_view.html",
|
||||
{
|
||||
"now_task": get_now_task(db),
|
||||
"next_task": get_next_task(db),
|
||||
"later_tasks_count": len(get_later_tasks(db)),
|
||||
},
|
||||
@@ -154,7 +178,8 @@ async def get_evening_ritual_form(request: Request, db: Session = Depends(get_db
|
||||
if not journal_entry:
|
||||
raise HTTPException(status_code=404, detail="No journal entry for today")
|
||||
return templates.TemplateResponse(
|
||||
"calm/evening_ritual_form.html", {"request": request, "journal_entry": journal_entry})
|
||||
"calm/evening_ritual_form.html", {"request": request, "journal_entry": journal_entry}
|
||||
)
|
||||
|
||||
|
||||
@router.post("/calm/ritual/evening", response_class=HTMLResponse)
|
||||
@@ -175,9 +200,13 @@ async def post_evening_ritual(
|
||||
db.add(journal_entry)
|
||||
|
||||
# Archive any remaining active tasks
|
||||
active_tasks = db.query(Task).filter(Task.state.in_([TaskState.NOW, TaskState.NEXT, TaskState.LATER])).all()
|
||||
active_tasks = (
|
||||
db.query(Task)
|
||||
.filter(Task.state.in_([TaskState.NOW, TaskState.NEXT, TaskState.LATER]))
|
||||
.all()
|
||||
)
|
||||
for task in active_tasks:
|
||||
task.state = TaskState.DEFERRED # Or DONE, depending on desired archiving logic
|
||||
task.state = TaskState.DEFERRED # Or DONE, depending on desired archiving logic
|
||||
task.deferred_at = datetime.utcnow()
|
||||
db.add(task)
|
||||
|
||||
@@ -221,7 +250,7 @@ async def start_task(
|
||||
):
|
||||
current_now_task = get_now_task(db)
|
||||
if current_now_task and current_now_task.id != task_id:
|
||||
current_now_task.state = TaskState.NEXT # Demote current NOW to NEXT
|
||||
current_now_task.state = TaskState.NEXT # Demote current NOW to NEXT
|
||||
db.add(current_now_task)
|
||||
|
||||
task = db.query(Task).filter(Task.id == task_id).first()
|
||||
@@ -322,7 +351,7 @@ async def reorder_tasks(
|
||||
):
|
||||
# Reorder LATER tasks
|
||||
if later_task_ids:
|
||||
ids_in_order = [int(x.strip()) for x in later_task_ids.split(',') if x.strip()]
|
||||
ids_in_order = [int(x.strip()) for x in later_task_ids.split(",") if x.strip()]
|
||||
for index, task_id in enumerate(ids_in_order):
|
||||
task = db.query(Task).filter(Task.id == task_id).first()
|
||||
if task and task.state == TaskState.LATER:
|
||||
@@ -332,16 +361,18 @@ async def reorder_tasks(
|
||||
# Handle NEXT task if it's part of the reorder (e.g., moved from LATER to NEXT explicitly)
|
||||
if next_task_id:
|
||||
task = db.query(Task).filter(Task.id == next_task_id).first()
|
||||
if task and task.state == TaskState.LATER: # Only if it was a LATER task being promoted manually
|
||||
if (
|
||||
task and task.state == TaskState.LATER
|
||||
): # Only if it was a LATER task being promoted manually
|
||||
# Demote current NEXT to LATER
|
||||
current_next = get_next_task(db)
|
||||
if current_next:
|
||||
current_next.state = TaskState.LATER
|
||||
current_next.sort_order = len(get_later_tasks(db)) # Add to end of later
|
||||
current_next.sort_order = len(get_later_tasks(db)) # Add to end of later
|
||||
db.add(current_next)
|
||||
|
||||
task.state = TaskState.NEXT
|
||||
task.sort_order = 0 # NEXT tasks don't really need sort_order, but for consistency
|
||||
task.sort_order = 0 # NEXT tasks don't really need sort_order, but for consistency
|
||||
db.add(task)
|
||||
|
||||
db.commit()
|
||||
|
||||
Reference in New Issue
Block a user