Skip to content

Commit f80f490

Browse files
authored
Merge pull request #3 from Sjeff/update-3.0.4
Update 3.0.4
2 parents b874a8b + 6196f28 commit f80f490

47 files changed

Lines changed: 292 additions & 222 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: Tests
22

3-
on: [push, pull_request]
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
47

58
jobs:
69
backend-tests:

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,20 @@ alembic upgrade head
197197

198198
## Changelog
199199

200+
### v3.0.4
201+
202+
All changes in this release were made in collaboration with [Claude](https://claude.ai) (Anthropic).
203+
204+
#### Bug fixes
205+
206+
- Fixed automation cycle crash when the Steam API returns no review data for a game — review fields (`review_score`, `total_positive`, `total_negative`, `total_reviews`) now fall back to `0` instead of `None` to satisfy the database `NOT NULL` constraint
207+
208+
#### Code quality
209+
210+
- Replaced all uses of the deprecated `datetime.utcnow()` (52 call sites across 21 files + 19 test files) with `datetime.now(timezone.utc)` — required for Python 3.12+ compatibility
211+
- Added `TZDateTime` SQLAlchemy TypeDecorator to re-attach `timezone.utc` when reading datetimes from SQLite, preventing naive/aware comparison errors
212+
- Fixed CI workflow running 4 jobs per PR instead of 2 — push trigger now limited to `master`
213+
200214
### v3.0.3
201215

202216
All changes in this release were made in collaboration with [Claude](https://claude.ai) (Anthropic).

backend/src/api/routers/system.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import json
99
from io import StringIO
1010
from typing import Dict, Any
11-
from datetime import datetime
11+
from datetime import datetime, timezone
1212

1313
from fastapi import APIRouter, Query
1414
from fastapi.responses import StreamingResponse
@@ -45,7 +45,7 @@ async def health_check() -> Dict[str, Any]:
4545
return create_success_response(
4646
data={
4747
"status": "healthy",
48-
"timestamp": datetime.utcnow().isoformat(),
48+
"timestamp": datetime.now(timezone.utc).isoformat(),
4949
"version": "0.1.0",
5050
}
5151
)
@@ -236,12 +236,12 @@ async def export_logs(
236236
writer.writerows(logs_data)
237237
content = output.getvalue()
238238
media_type = "text/csv"
239-
filename = f"logs_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.csv"
239+
filename = f"logs_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.csv"
240240
else:
241241
# Generate JSON
242242
content = json.dumps(logs_data, indent=2)
243243
media_type = "application/json"
244-
filename = f"logs_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.json"
244+
filename = f"logs_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json"
245245

246246
return StreamingResponse(
247247
iter([content]),

backend/src/api/schemas/common.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from typing import Any, Optional, Generic, TypeVar
8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from pydantic import BaseModel, Field
1010

1111

@@ -313,7 +313,7 @@ def create_success_response(
313313
True
314314
"""
315315
meta = ResponseMeta(
316-
timestamp=datetime.utcnow().isoformat() + "Z",
316+
timestamp=datetime.now(timezone.utc).isoformat() + "Z",
317317
request_id=request_id,
318318
page=page,
319319
per_page=per_page,
@@ -356,7 +356,7 @@ def create_error_response(
356356
False
357357
"""
358358
meta = ResponseMeta(
359-
timestamp=datetime.utcnow().isoformat() + "Z",
359+
timestamp=datetime.now(timezone.utc).isoformat() + "Z",
360360
request_id=request_id,
361361
)
362362

backend/src/api/schemas/entry.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from typing import Optional
8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from pydantic import BaseModel, Field
1010

1111

@@ -59,7 +59,7 @@ class EntryResponse(EntryBase):
5959
... points_spent=50,
6060
... entry_type="manual",
6161
... status="success",
62-
... entered_at=datetime.utcnow()
62+
... entered_at=datetime.now(timezone.utc)
6363
... )
6464
"""
6565

backend/src/api/schemas/game.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from typing import Optional
8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from pydantic import BaseModel, Field
1010

1111

@@ -102,7 +102,7 @@ class GameResponse(GameBase):
102102
... name="Portal 2",
103103
... type="game",
104104
... review_score=9,
105-
... last_refreshed_at=datetime.utcnow()
105+
... last_refreshed_at=datetime.now(timezone.utc)
106106
... )
107107
"""
108108

@@ -214,7 +214,7 @@ class GameRefreshResponse(BaseModel):
214214
>>> response = GameRefreshResponse(
215215
... refreshed=True,
216216
... message="Game data refreshed successfully",
217-
... last_refreshed_at=datetime.utcnow()
217+
... last_refreshed_at=datetime.now(timezone.utc)
218218
... )
219219
"""
220220

backend/src/api/schemas/giveaway.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from typing import Optional
8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from pydantic import BaseModel, Field, field_serializer
1010

1111

@@ -102,7 +102,7 @@ class GiveawayResponse(GiveawayBase):
102102
... url="https://www.steamgifts.com/giveaway/AbCd1/",
103103
... game_name="Portal 2",
104104
... price=50,
105-
... discovered_at=datetime.utcnow()
105+
... discovered_at=datetime.now(timezone.utc)
106106
... )
107107
"""
108108

backend/src/api/schemas/settings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
from typing import Optional
8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from pydantic import BaseModel, Field, field_validator
1010

1111

@@ -163,8 +163,8 @@ class SettingsResponse(SettingsBase):
163163
... id=1,
164164
... user_agent="Mozilla/5.0...",
165165
... autojoin_enabled=True,
166-
... created_at=datetime.utcnow(),
167-
... updated_at=datetime.utcnow()
166+
... created_at=datetime.now(timezone.utc),
167+
... updated_at=datetime.now(timezone.utc)
168168
... )
169169
"""
170170

backend/src/core/events.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import asyncio
88
import json
9-
from datetime import datetime
9+
from datetime import datetime, timezone
1010
from typing import Dict, Any, Set
1111
from fastapi import WebSocket
1212

@@ -123,7 +123,7 @@ async def broadcast_event(self, event_type: str, data: Dict[str, Any]) -> None:
123123
event = {
124124
"type": event_type,
125125
"data": data,
126-
"timestamp": datetime.utcnow().isoformat(),
126+
"timestamp": datetime.now(timezone.utc).isoformat(),
127127
}
128128

129129
# Track disconnected clients for removal

backend/src/models/account.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from sqlalchemy import String, Integer, Boolean, DateTime
55
from sqlalchemy.orm import Mapped, mapped_column
66

7-
from models.base import Base, TimestampMixin
7+
from models.base import Base, TimestampMixin, TZDateTime
88

99

1010
class Account(Base, TimestampMixin):
@@ -167,7 +167,7 @@ class Account(Base, TimestampMixin):
167167

168168
# ==================== Metadata ====================
169169
last_synced_at: Mapped[datetime | None] = mapped_column(
170-
DateTime,
170+
TZDateTime,
171171
nullable=True,
172172
comment="Last sync with SteamGifts",
173173
)

0 commit comments

Comments
 (0)