diff --git a/src/dashboard/models/calm.py b/src/dashboard/models/calm.py index 3b85446..403235c 100644 --- a/src/dashboard/models/calm.py +++ b/src/dashboard/models/calm.py @@ -1,4 +1,4 @@ -from datetime import date, datetime +from datetime import UTC, date, datetime from enum import StrEnum from sqlalchemy import JSON, Boolean, Column, Date, DateTime, Index, Integer, String @@ -40,8 +40,13 @@ class Task(Base): deferred_at = Column(DateTime, nullable=True) # Timestamps - created_at = Column(DateTime, default=datetime.utcnow, nullable=False) - updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) + created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False) + updated_at = Column( + DateTime, + default=lambda: datetime.now(UTC), + onupdate=lambda: datetime.now(UTC), + nullable=False, + ) __table_args__ = (Index("ix_task_state_order", "state", "sort_order"),) @@ -59,4 +64,4 @@ class JournalEntry(Base): gratitude = Column(String(500), nullable=True) energy_level = Column(Integer, nullable=True) # User-reported, 1-10 - created_at = Column(DateTime, default=datetime.utcnow, nullable=False) + created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False) diff --git a/src/dashboard/routes/tasks.py b/src/dashboard/routes/tasks.py index 027d049..93669b5 100644 --- a/src/dashboard/routes/tasks.py +++ b/src/dashboard/routes/tasks.py @@ -5,7 +5,7 @@ import sqlite3 import uuid from collections.abc import Generator from contextlib import closing, contextmanager -from datetime import datetime +from datetime import UTC, datetime from pathlib import Path from fastapi import APIRouter, Form, HTTPException, Request @@ -219,7 +219,7 @@ async def create_task_form( raise HTTPException(status_code=400, detail="Task title cannot be empty") task_id = str(uuid.uuid4()) - now = datetime.utcnow().isoformat() + now = datetime.now(UTC).isoformat() priority = priority if priority in VALID_PRIORITIES else "normal" with _get_db() as db: @@ -287,7 +287,7 @@ async def modify_task( async def _set_status(request: Request, task_id: str, new_status: str): """Helper to update status and return refreshed task card.""" completed_at = ( - datetime.utcnow().isoformat() if new_status in ("completed", "vetoed", "failed") else None + datetime.now(UTC).isoformat() if new_status in ("completed", "vetoed", "failed") else None ) with _get_db() as db: db.execute( @@ -316,7 +316,7 @@ async def api_create_task(request: Request): raise HTTPException(422, "title is required") task_id = str(uuid.uuid4()) - now = datetime.utcnow().isoformat() + now = datetime.now(UTC).isoformat() priority = body.get("priority", "normal") if priority not in VALID_PRIORITIES: priority = "normal" @@ -358,7 +358,7 @@ async def api_update_status(task_id: str, request: Request): raise HTTPException(422, f"Invalid status. Must be one of: {VALID_STATUSES}") completed_at = ( - datetime.utcnow().isoformat() if new_status in ("completed", "vetoed", "failed") else None + datetime.now(UTC).isoformat() if new_status in ("completed", "vetoed", "failed") else None ) with _get_db() as db: db.execute( diff --git a/src/dashboard/routes/work_orders.py b/src/dashboard/routes/work_orders.py index c400acd..5d489f4 100644 --- a/src/dashboard/routes/work_orders.py +++ b/src/dashboard/routes/work_orders.py @@ -5,7 +5,7 @@ import sqlite3 import uuid from collections.abc import Generator from contextlib import closing, contextmanager -from datetime import datetime +from datetime import UTC, datetime from pathlib import Path from fastapi import APIRouter, Form, HTTPException, Request @@ -144,7 +144,7 @@ async def submit_work_order( related_files: str = Form(""), ): wo_id = str(uuid.uuid4()) - now = datetime.utcnow().isoformat() + now = datetime.now(UTC).isoformat() priority = priority if priority in PRIORITIES else "medium" category = category if category in CATEGORIES else "suggestion" @@ -211,7 +211,7 @@ async def active_partial(request: Request): async def _update_status(request: Request, wo_id: str, new_status: str, **extra): completed_at = ( - datetime.utcnow().isoformat() if new_status in ("completed", "rejected") else None + datetime.now(UTC).isoformat() if new_status in ("completed", "rejected") else None ) with _get_db() as db: sets = ["status=?", "completed_at=COALESCE(?, completed_at)"] diff --git a/src/timmy/mcp_tools.py b/src/timmy/mcp_tools.py index 3971406..50b78e6 100644 --- a/src/timmy/mcp_tools.py +++ b/src/timmy/mcp_tools.py @@ -30,7 +30,7 @@ import shutil import sqlite3 import uuid from contextlib import closing -from datetime import datetime +from datetime import UTC, datetime from pathlib import Path import httpx @@ -196,7 +196,7 @@ def _bridge_to_work_order(title: str, body: str, category: str) -> None: body, category, "timmy-thinking", - datetime.utcnow().isoformat(), + datetime.now(UTC).isoformat(), ), ) conn.commit()