diff --git a/src/backend/api/routers/setup.py b/src/backend/api/routers/setup.py index b9c4aaa..39767ff 100644 --- a/src/backend/api/routers/setup.py +++ b/src/backend/api/routers/setup.py @@ -6,7 +6,7 @@ NOT protected by API Key auth (standalone access). import hmac import random from datetime import datetime, timedelta -from src.backend.utils.tempo import utcnow +from src.backend.utils.tempo import iso_utc, utcnow from pathlib import Path from alembic import command @@ -604,8 +604,8 @@ async def list_users(body: PasswordBody): "roles": u.roles or [], "is_admin": u.is_admin, "active": u.active, - "created_at": u.created_at.isoformat() if u.created_at else None, - "last_login": u.last_login.isoformat() if u.last_login else None, + "created_at": iso_utc(u.created_at) or None, + "last_login": iso_utc(u.last_login) or None, } for u in users ], diff --git a/src/backend/services/report_service.py b/src/backend/services/report_service.py index a5ded88..975a41d 100644 --- a/src/backend/services/report_service.py +++ b/src/backend/services/report_service.py @@ -33,6 +33,11 @@ _jinja_env = Environment( ) +def _giorno_locale(dt: datetime) -> str: + """UTC naive filter bound -> local calendar day (YYYY-MM-DD).""" + return to_local(dt).strftime("%Y-%m-%d") + + async def _query_measurements( db: AsyncSession, recipe_id: int, @@ -324,9 +329,9 @@ async def generate_spc_report( if version_id: filters_desc.append(f"Version: {version_id}") if date_from: - filters_desc.append(f"From: {date_from.strftime('%Y-%m-%d')}") + filters_desc.append(f"From: {_giorno_locale(date_from)}") if date_to: - filters_desc.append(f"To: {date_to.strftime('%Y-%m-%d')}") + filters_desc.append(f"To: {_giorno_locale(date_to)}") if lot_number: filters_desc.append(f"Lot: {lot_number}") if serial_number: @@ -415,9 +420,9 @@ async def generate_measurement_report( if version_id: filters_desc.append(f"Version: {version_id}") if date_from: - filters_desc.append(f"From: {date_from.strftime('%Y-%m-%d')}") + filters_desc.append(f"From: {_giorno_locale(date_from)}") if date_to: - filters_desc.append(f"To: {date_to.strftime('%Y-%m-%d')}") + filters_desc.append(f"To: {_giorno_locale(date_to)}") if lot_number: filters_desc.append(f"Lot: {lot_number}") if serial_number: diff --git a/src/backend/tests/test_tempo.py b/src/backend/tests/test_tempo.py index 98b5eb5..3107a5e 100644 --- a/src/backend/tests/test_tempo.py +++ b/src/backend/tests/test_tempo.py @@ -106,3 +106,8 @@ async def test_report_generated_at_is_local_time( await report_service.generate_measurement_report(db_session, recipe.id) assert "Generated 2026-10-06 10:00" in captured["html"] + + +def test_report_filter_day_is_local(): + """UTC naive 22:00 of Oct 5 is already Oct 6 in Europe/Rome (#42).""" + assert report_service._giorno_locale(datetime(2026, 10, 5, 22, 0, 0)) == "2026-10-06"